winecfg: Don't mix the strings in unix and windows locales

Dmitry Timoshkov dmitry at codeweavers.com
Thu Jan 3 07:29:24 CST 2008


Hello,

this patch should fix the problem reported in the bug 10997.

Changelog:
    winecfg: Don't mix the strings in unix and windows locales.
---
 programs/winecfg/driveui.c |   20 ++++++------
 programs/winecfg/theme.c   |   67 +++++++++++++++++++++++++++++++------------
 programs/winecfg/winecfg.h |   16 ++++++++++-
 3 files changed, 73 insertions(+), 30 deletions(-)

diff --git a/programs/winecfg/driveui.c b/programs/winecfg/driveui.c
index 2267764..47aed18 100644
--- a/programs/winecfg/driveui.c
+++ b/programs/winecfg/driveui.c
@@ -563,13 +563,13 @@ static void paint(HWND dialog)
     EndPaint(dialog, &ps);
 }
 
-BOOL browse_for_unix_folder(HWND dialog, char *pszPath)
+BOOL browse_for_unix_folder(HWND dialog, WCHAR *pszPath)
 {
     static WCHAR wszUnixRootDisplayName[] = 
         { ':',':','{','C','C','7','0','2','E','B','2','-','7','D','C','5','-','1','1','D','9','-',
           'C','6','8','7','-','0','0','0','4','2','3','8','A','0','1','C','D','}', 0 };
-    char pszChoosePath[256];
-    BROWSEINFOA bi = {
+    WCHAR pszChoosePath[FILENAME_MAX];
+    BROWSEINFOW bi = {
         dialog,
         NULL,
         NULL,
@@ -583,7 +583,7 @@ BOOL browse_for_unix_folder(HWND dialog, char *pszPath)
     LPITEMIDLIST pidlUnixRoot, pidlSelectedPath;
     HRESULT hr;
    
-    LoadString(GetModuleHandle(NULL), IDS_CHOOSE_PATH, pszChoosePath, 256);
+    LoadStringW(GetModuleHandle(NULL), IDS_CHOOSE_PATH, pszChoosePath, FILENAME_MAX);
     
     hr = SHGetDesktopFolder(&pDesktop);
     if (!SUCCEEDED(hr)) return FALSE;
@@ -596,12 +596,12 @@ BOOL browse_for_unix_folder(HWND dialog, char *pszPath)
     }
 
     bi.pidlRoot = pidlUnixRoot;
-    pidlSelectedPath = SHBrowseForFolderA(&bi);
+    pidlSelectedPath = SHBrowseForFolderW(&bi);
     SHFree(pidlUnixRoot);
     
     if (pidlSelectedPath) {
         STRRET strSelectedPath;
-        char *pszSelectedPath;
+        WCHAR *pszSelectedPath;
         HRESULT hr;
         
         hr = IShellFolder_GetDisplayNameOf(pDesktop, pidlSelectedPath, SHGDN_FORPARSING, 
@@ -612,11 +612,11 @@ BOOL browse_for_unix_folder(HWND dialog, char *pszPath)
             return FALSE;
         }
 
-        hr = StrRetToStr(&strSelectedPath, pidlSelectedPath, &pszSelectedPath);
+        hr = StrRetToStrW(&strSelectedPath, pidlSelectedPath, &pszSelectedPath);
         SHFree(pidlSelectedPath);
         if (!SUCCEEDED(hr)) return FALSE;
 
-        lstrcpy(pszPath, pszSelectedPath);
+        lstrcpyW(pszPath, pszSelectedPath);
         
         CoTaskMemFree(pszSelectedPath);
         return TRUE;
@@ -740,9 +740,9 @@ DriveDlgProc (HWND dialog, UINT msg, WPARAM wParam, LPARAM lParam)
 
                 case IDC_BUTTON_BROWSE_PATH:
                 {
-                    char szTargetPath[FILENAME_MAX];
+                    WCHAR szTargetPath[FILENAME_MAX];
                     if (browse_for_unix_folder(dialog, szTargetPath)) 
-                        set_text(dialog, IDC_EDIT_PATH, szTargetPath);
+                        set_textW(dialog, IDC_EDIT_PATH, szTargetPath);
                     break;
                 }
 
diff --git a/programs/winecfg/theme.c b/programs/winecfg/theme.c
index ca67914..b7e75aa 100644
--- a/programs/winecfg/theme.c
+++ b/programs/winecfg/theme.c
@@ -705,7 +705,7 @@ static void on_theme_install(HWND dialog)
 /* Information about symbolic link targets of certain User Shell Folders. */
 struct ShellFolderInfo {
     int nFolder;
-    char szLinkTarget[FILENAME_MAX];
+    char szLinkTarget[FILENAME_MAX]; /* in unix locale */
 };
 
 static struct ShellFolderInfo asfiInfo[] = {
@@ -720,6 +720,19 @@ static struct ShellFolderInfo *psfiSelected = NULL;
 
 #define NUM_ELEMS(x) (sizeof(x)/sizeof(*(x)))
 
+/* create a unicode string from a string in Unix locale */
+static WCHAR *strdupU2W(const char *unix_str)
+{
+    WCHAR *unicode_str;
+    int lenW;
+
+    lenW = MultiByteToWideChar(CP_UNIXCP, 0, unix_str, -1, NULL, 0);
+    unicode_str = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
+    if (unicode_str)
+        MultiByteToWideChar(CP_UNIXCP, 0, unix_str, -1, unicode_str, lenW);
+    return unicode_str;
+}
+
 static void init_shell_folder_listview_headers(HWND dialog) {
     LVCOLUMN listColumn;
     RECT viewRect;
@@ -773,14 +786,14 @@ static void read_shell_folder_link_targets(void) {
 
 static void update_shell_folder_listview(HWND dialog) {
     int i;
-    LVITEM item;
+    LVITEMW item;
     LONG lSelected = SendDlgItemMessage(dialog, IDC_LIST_SFPATHS, LVM_GETNEXTITEM, (WPARAM)-1, 
                                         MAKELPARAM(LVNI_SELECTED,0));
     
     SendDlgItemMessage(dialog, IDC_LIST_SFPATHS, LVM_DELETEALLITEMS, 0, 0);
 
     for (i=0; i<NUM_ELEMS(asfiInfo); i++) {
-        char buffer[MAX_PATH];
+        WCHAR buffer[MAX_PATH];
         HRESULT hr;
         LPITEMIDLIST pidlCurrent;
 
@@ -794,7 +807,7 @@ static void update_shell_folder_listview(HWND dialog) {
                 STRRET strRet;
                 hr = IShellFolder_GetDisplayNameOf(psfParent, pidlLast, SHGDN_FORADDRESSBAR, &strRet);
                 if (SUCCEEDED(hr)) {
-                    hr = StrRetToBufA(&strRet, pidlLast, buffer, 256);
+                    hr = StrRetToBufW(&strRet, pidlLast, buffer, MAX_PATH);
                 }
                 IShellFolder_Release(psfParent);
             }
@@ -804,7 +817,7 @@ static void update_shell_folder_listview(HWND dialog) {
         /* If there's a dangling symlink for the current shell folder, SHGetFolderLocation
          * will fail above. We fall back to the (non-verified) path of the shell folder. */
         if (FAILED(hr)) {
-            hr = SHGetFolderPath(dialog, asfiInfo[i].nFolder|CSIDL_FLAG_DONT_VERIFY, NULL, 
+            hr = SHGetFolderPathW(dialog, asfiInfo[i].nFolder|CSIDL_FLAG_DONT_VERIFY, NULL,
                                  SHGFP_TYPE_CURRENT, buffer);
         }
     
@@ -813,13 +826,14 @@ static void update_shell_folder_listview(HWND dialog) {
         item.iSubItem = 0;
         item.pszText = buffer;
         item.lParam = (LPARAM)&asfiInfo[i];
-        SendDlgItemMessage(dialog, IDC_LIST_SFPATHS, LVM_INSERTITEM, 0, (LPARAM)&item);
+        SendDlgItemMessage(dialog, IDC_LIST_SFPATHS, LVM_INSERTITEMW, 0, (LPARAM)&item);
 
         item.mask = LVIF_TEXT;
         item.iItem = i;
         item.iSubItem = 1;
-        item.pszText = asfiInfo[i].szLinkTarget;
-        SendDlgItemMessage(dialog, IDC_LIST_SFPATHS, LVM_SETITEM, 0, (LPARAM)&item);
+        item.pszText = strdupU2W(asfiInfo[i].szLinkTarget);
+        SendDlgItemMessage(dialog, IDC_LIST_SFPATHS, LVM_SETITEMW, 0, (LPARAM)&item);
+        HeapFree(GetProcessHeap(), 0, item.pszText);
     }
 
     /* Ensure that the previously selected item is selected again. */
@@ -837,20 +851,23 @@ static void on_shell_folder_selection_changed(HWND hDlg, LPNMLISTVIEW lpnm) {
         psfiSelected = (struct ShellFolderInfo *)lpnm->lParam;
         EnableWindow(GetDlgItem(hDlg, IDC_LINK_SFPATH), 1);
         if (strlen(psfiSelected->szLinkTarget)) {
+            WCHAR *link;
             CheckDlgButton(hDlg, IDC_LINK_SFPATH, BST_CHECKED);
             EnableWindow(GetDlgItem(hDlg, IDC_EDIT_SFPATH), 1);
             EnableWindow(GetDlgItem(hDlg, IDC_BROWSE_SFPATH), 1);
-            SetWindowText(GetDlgItem(hDlg, IDC_EDIT_SFPATH), psfiSelected->szLinkTarget);
+            link = strdupU2W(psfiSelected->szLinkTarget);
+            set_textW(hDlg, IDC_EDIT_SFPATH, link);
+            HeapFree(GetProcessHeap(), 0, link);
         } else {
             CheckDlgButton(hDlg, IDC_LINK_SFPATH, BST_UNCHECKED);
             EnableWindow(GetDlgItem(hDlg, IDC_EDIT_SFPATH), 0);
             EnableWindow(GetDlgItem(hDlg, IDC_BROWSE_SFPATH), 0);
-            SetWindowText(GetDlgItem(hDlg, IDC_EDIT_SFPATH), "");
+            set_text(hDlg, IDC_EDIT_SFPATH, "");
         }
     } else {
         psfiSelected = NULL;
         CheckDlgButton(hDlg, IDC_LINK_SFPATH, BST_UNCHECKED);
-        SetWindowText(GetDlgItem(hDlg, IDC_EDIT_SFPATH), "");
+        set_text(hDlg, IDC_EDIT_SFPATH, "");
         EnableWindow(GetDlgItem(hDlg, IDC_LINK_SFPATH), 0);
         EnableWindow(GetDlgItem(hDlg, IDC_EDIT_SFPATH), 0);
         EnableWindow(GetDlgItem(hDlg, IDC_BROWSE_SFPATH), 0);
@@ -860,8 +877,8 @@ static void on_shell_folder_selection_changed(HWND hDlg, LPNMLISTVIEW lpnm) {
 /* Keep the contents of the edit control, the listview control and the symlink 
  * information in sync. */
 static void on_shell_folder_edit_changed(HWND hDlg) {
-    LVITEM item;
-    char *text = get_text(hDlg, IDC_EDIT_SFPATH);
+    LVITEMW item;
+    WCHAR *text = get_textW(hDlg, IDC_EDIT_SFPATH);
     LONG iSel = SendDlgItemMessage(hDlg, IDC_LIST_SFPATHS, LVM_GETNEXTITEM, -1,
                                    MAKELPARAM(LVNI_SELECTED,0));
     
@@ -870,14 +887,16 @@ static void on_shell_folder_edit_changed(HWND hDlg) {
         return;
     }
 
-    strncpy(psfiSelected->szLinkTarget, text, FILENAME_MAX);
-    HeapFree(GetProcessHeap(), 0, text);
+    WideCharToMultiByte(CP_UNIXCP, 0, text, -1,
+                        psfiSelected->szLinkTarget, FILENAME_MAX, NULL, NULL);
 
     item.mask = LVIF_TEXT;
     item.iItem = iSel;
     item.iSubItem = 1;
-    item.pszText = psfiSelected->szLinkTarget;
-    SendDlgItemMessage(hDlg, IDC_LIST_SFPATHS, LVM_SETITEM, 0, (LPARAM)&item);
+    item.pszText = text;
+    SendDlgItemMessage(hDlg, IDC_LIST_SFPATHS, LVM_SETITEMW, 0, (LPARAM)&item);
+
+    HeapFree(GetProcessHeap(), 0, text);
 
     SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0);
 }
@@ -1158,15 +1177,25 @@ ThemeDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
                             break;
 
                         case IDC_BROWSE_SFPATH:
-                            if (browse_for_unix_folder(hDlg, psfiSelected->szLinkTarget)) {
+                        {
+                            WCHAR link[FILENAME_MAX];
+                            if (browse_for_unix_folder(hDlg, link)) {
+                                WideCharToMultiByte(CP_UNIXCP, 0, link, -1,
+                                                    psfiSelected->szLinkTarget, FILENAME_MAX,
+                                                    NULL, NULL);
                                 update_shell_folder_listview(hDlg);
                                 SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0);
                             }
                             break;
+                        }
 
                         case IDC_LINK_SFPATH:
                             if (IsDlgButtonChecked(hDlg, IDC_LINK_SFPATH)) {
-                                if (browse_for_unix_folder(hDlg, psfiSelected->szLinkTarget)) {
+                                WCHAR link[FILENAME_MAX];
+                                if (browse_for_unix_folder(hDlg, link)) {
+                                    WideCharToMultiByte(CP_UNIXCP, 0, link, -1,
+                                                        psfiSelected->szLinkTarget, FILENAME_MAX,
+                                                        NULL, NULL);
                                     update_shell_folder_listview(hDlg);
                                     SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0);
                                 } else {
diff --git a/programs/winecfg/winecfg.h b/programs/winecfg/winecfg.h
index 4ad7129..b0e2d39 100644
--- a/programs/winecfg/winecfg.h
+++ b/programs/winecfg/winecfg.h
@@ -109,7 +109,7 @@ long drive_available_mask(char letter);
 BOOL add_drive(const char letter, const char *targetpath, const char *label, const char *serial, unsigned int type);
 void delete_drive(struct drive *pDrive);
 void apply_drive_changes(void);
-BOOL browse_for_unix_folder(HWND dialog, char *pszPath);
+BOOL browse_for_unix_folder(HWND dialog, WCHAR *pszPath);
 extern struct drive drives[26]; /* one for each drive letter */
 
 BOOL gui_mode;
@@ -141,11 +141,25 @@ static inline char *get_text(HWND dialog, WORD id)
     return result;
 }
 
+static inline WCHAR *get_textW(HWND dialog, WORD id)
+{
+    HWND item = GetDlgItem(dialog, id);
+    int len = GetWindowTextLengthW(item) + 1;
+    WCHAR *result = len ? HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)) : NULL;
+    if (!result || GetWindowTextW(item, result, len) == 0) return NULL;
+    return result;
+}
+
 static inline void set_text(HWND dialog, WORD id, const char *text)
 {
     SetWindowText(GetDlgItem(dialog, id), text);
 }
 
+static inline void set_textW(HWND dialog, WORD id, const WCHAR *text)
+{
+    SetWindowTextW(GetDlgItem(dialog, id), text);
+}
+
 #define WINE_KEY_ROOT "Software\\Wine"
 #define MAXBUFLEN 256
 
-- 
1.5.3.7






More information about the wine-patches mailing list