[COMDLG32] Save open/save location by extension (#1514)
[reactos.git] / dll / win32 / comdlg32 / filedlg.c
index 150e29d..eed9f59 100644 (file)
  *
  */
 
-// RegGetValueW is supported by Win2k3 SP1 but headers need Win Vista
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600
-
 #include "config.h"
 #include "wine/port.h"
 
 
 #define COBJMACROS
 #define NONAMELESSUNION
-#define NONAMELESSSTRUCT
 
 #include "windef.h"
 #include "winbase.h"
 #include "winternl.h"
 #include "winnls.h"
 #include "wingdi.h"
+#ifdef __REACTOS__
+/* RegGetValueW is supported by Win2k3 SP1 but headers need Win Vista */
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#endif
 #include "winreg.h"
 #include "winuser.h"
 #include "commdlg.h"
 #include "dlgs.h"
 #include "cdlg.h"
-#include "filedlg31.h"
 #include "cderr.h"
 #include "shellapi.h"
 #include "shlobj.h"
@@ -81,6 +80,7 @@
 
 #include "wine/unicode.h"
 #include "wine/debug.h"
+#include "wine/heap.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
 
@@ -89,8 +89,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
 OFN_NODEREFERENCELINKS | OFN_NOREADONLYRETURN |\
 OFN_NOTESTFILECREATE /*| OFN_USEMONIKERS*/)
 
-#define IsHooked(fodInfos) \
-       ((fodInfos->ofnInfos->Flags & OFN_ENABLEHOOK) && fodInfos->ofnInfos->lpfnHook)
 /***********************************************************************
  * Data structure and global variables
  */
@@ -115,7 +113,6 @@ typedef struct tagLookInInfo
  */
 
 /* Draw item constant */
-#define ICONWIDTH 18
 #define XTEXTOFFSET 3
 
 /* AddItem flags*/
@@ -129,47 +126,21 @@ typedef struct tagLookInInfo
 /* Undefined windows message sent by CreateViewObject*/
 #define WM_GETISHELLBROWSER  WM_USER+7
 
+#define TBPLACES_CMDID_PLACE0    0xa064
+#define TBPLACES_CMDID_PLACE1    0xa065
+#define TBPLACES_CMDID_PLACE2    0xa066
+#define TBPLACES_CMDID_PLACE3    0xa067
+#define TBPLACES_CMDID_PLACE4    0xa068
+
 /* NOTE
  * Those macros exist in windowsx.h. However, you can't really use them since
  * they rely on the UNICODE defines and can't be used inside Wine itself.
  */
 
 /* Combo box macros */
-#define CBAddString(hwnd,str) \
-    SendMessageW(hwnd, CB_ADDSTRING, 0, (LPARAM)(str));
-
-#define CBInsertString(hwnd,str,pos) \
-    SendMessageW(hwnd, CB_INSERTSTRING, (WPARAM)(pos), (LPARAM)(str));
-
-#define CBDeleteString(hwnd,pos) \
-    SendMessageW(hwnd, CB_DELETESTRING, (WPARAM)(pos), 0);
-
-#define CBSetItemDataPtr(hwnd,iItemId,dataPtr) \
-    SendMessageW(hwnd, CB_SETITEMDATA, (WPARAM)(iItemId), (LPARAM)(dataPtr));
-
 #define CBGetItemDataPtr(hwnd,iItemId) \
     SendMessageW(hwnd, CB_GETITEMDATA, (WPARAM)(iItemId), 0)
 
-#define CBGetLBText(hwnd,iItemId,str) \
-    SendMessageW(hwnd, CB_GETLBTEXT, (WPARAM)(iItemId), (LPARAM)(str));
-
-#define CBGetCurSel(hwnd) \
-    SendMessageW(hwnd, CB_GETCURSEL, 0, 0);
-
-#define CBSetCurSel(hwnd,pos) \
-    SendMessageW(hwnd, CB_SETCURSEL, (WPARAM)(pos), 0);
-
-#define CBGetCount(hwnd) \
-    SendMessageW(hwnd, CB_GETCOUNT, 0, 0);
-#define CBShowDropDown(hwnd,show) \
-    SendMessageW(hwnd, CB_SHOWDROPDOWN, (WPARAM)(show), 0);
-#define CBSetItemHeight(hwnd,index,height) \
-    SendMessageW(hwnd, CB_SETITEMHEIGHT, (WPARAM)(index), (LPARAM)(height));
-
-#define CBSetExtendedUI(hwnd,flag) \
-    SendMessageW(hwnd, CB_SETEXTENDEDUI, (WPARAM)(flag), 0)
-
-const char FileOpenDlgInfosStr[] = "FileOpenDlgInfos"; /* windows property description string */
 static const char LookInInfosStr[] = "LookInInfos"; /* LOOKIN combo box property */
 static SIZE MemDialogSize = { 0, 0}; /* keep size of the (resizable) dialog */
 
@@ -180,6 +151,23 @@ static const WCHAR LastVisitedMRUW[] =
         'L','a','s','t','V','i','s','i','t','e','d','M','R','U',0};
 static const WCHAR MRUListW[] = {'M','R','U','L','i','s','t',0};
 
+static const WCHAR filedlg_info_propnameW[] = {'F','i','l','e','O','p','e','n','D','l','g','I','n','f','o','s',0};
+
+FileOpenDlgInfos *get_filedlg_infoptr(HWND hwnd)
+{
+    return GetPropW(hwnd, filedlg_info_propnameW);
+}
+
+static BOOL is_dialog_hooked(const FileOpenDlgInfos *info)
+{
+    return (info->ofnInfos->Flags & OFN_ENABLEHOOK) && info->ofnInfos->lpfnHook;
+}
+
+static BOOL filedialog_is_readonly_hidden(const FileOpenDlgInfos *info)
+{
+    return (info->ofnInfos->Flags & OFN_HIDEREADONLY) || (info->DlgInfos.dwDlgProp & FODPROP_SAVEDLG);
+}
+
 /***********************************************************************
  * Prototypes
  */
@@ -198,7 +186,6 @@ static LRESULT FILEDLG95_SHELL_Init(HWND hwnd);
 static BOOL    FILEDLG95_SHELL_UpFolder(HWND hwnd);
 static BOOL    FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb);
 static void    FILEDLG95_SHELL_Clean(HWND hwnd);
-static BOOL    FILEDLG95_SHELL_BrowseToDesktop(HWND hwnd);
 
 /* Functions used by the EDIT box */
 static int FILEDLG95_FILENAME_GetFileNames (HWND hwnd, LPWSTR * lpstrFileList, UINT * sizeUsed);
@@ -224,6 +211,10 @@ static void    FILEDLG95_LOOKIN_Clean(HWND hwnd);
 static void FILEDLG95_MRU_load_filename(LPWSTR stored_path);
 static WCHAR FILEDLG95_MRU_get_slot(LPCWSTR module_name, LPWSTR stored_path, PHKEY hkey_ret);
 static void FILEDLG95_MRU_save_filename(LPCWSTR filename);
+#ifdef __REACTOS__
+static void FILEDLG95_MRU_load_ext(LPWSTR stored_path, size_t cchMax, LPCWSTR defext);
+static void FILEDLG95_MRU_save_ext(LPCWSTR filename);
+#endif
 
 /* Miscellaneous tool functions */
 static HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPWSTR lpstrFileName);
@@ -232,16 +223,133 @@ LPITEMIDLIST  GetParentPidl(LPITEMIDLIST pidl);
 static LPITEMIDLIST GetPidlFromName(IShellFolder *psf,LPWSTR lpcstrFileName);
 static BOOL IsPidlFolder (LPSHELLFOLDER psf, LPCITEMIDLIST pidl);
 static UINT GetNumSelected( IDataObject *doSelected );
-
-/* Shell memory allocation */
-static void *MemAlloc(UINT size);
-static void MemFree(void *mem);
+static void COMCTL32_ReleaseStgMedium(STGMEDIUM medium);
 
 static INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 static INT_PTR FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 static BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPWSTR lpstrFileList, UINT nFileCount, UINT sizeUsed);
 static BOOL BrowseSelectedFolder(HWND hwnd);
 
+static BOOL get_config_key_as_dword(HKEY hkey, const WCHAR *name, DWORD *value)
+{
+    DWORD type, data, size;
+
+    size = sizeof(data);
+    if (hkey && !RegQueryValueExW(hkey, name, 0, &type, (BYTE *)&data, &size))
+    {
+        *value = data;
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static BOOL get_config_key_dword(HKEY hkey, const WCHAR *name, DWORD *value)
+{
+    DWORD type, data, size;
+
+    size = sizeof(data);
+    if (hkey && !RegQueryValueExW(hkey, name, 0, &type, (BYTE *)&data, &size) && type == REG_DWORD)
+    {
+        *value = data;
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static BOOL get_config_key_string(HKEY hkey, const WCHAR *name, WCHAR **value)
+{
+    DWORD type, size;
+    WCHAR *str;
+
+    if (hkey && !RegQueryValueExW(hkey, name, 0, &type, NULL, &size))
+    {
+        if (type != REG_SZ && type != REG_EXPAND_SZ)
+            return FALSE;
+    }
+
+    str = heap_alloc(size);
+    if (RegQueryValueExW(hkey, name, 0, &type, (BYTE *)str, &size))
+    {
+        heap_free(str);
+        return FALSE;
+    }
+
+    *value = str;
+    return TRUE;
+}
+
+static BOOL is_places_bar_enabled(const FileOpenDlgInfos *fodInfos)
+{
+    static const WCHAR noplacesbarW[] = {'N','o','P','l','a','c','e','s','B','a','r',0};
+    DWORD value;
+    HKEY hkey;
+
+    if (fodInfos->ofnInfos->lStructSize != sizeof(*fodInfos->ofnInfos) ||
+            (fodInfos->ofnInfos->FlagsEx & OFN_EX_NOPLACESBAR) ||
+           !(fodInfos->ofnInfos->Flags & OFN_EXPLORER))
+    {
+        return FALSE;
+    }
+
+    if (RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Comdlg32", &hkey))
+        return TRUE;
+
+    value = 0;
+    get_config_key_as_dword(hkey, noplacesbarW, &value);
+    RegCloseKey(hkey);
+    return value == 0;
+}
+
+static void filedlg_collect_places_pidls(FileOpenDlgInfos *fodInfos)
+{
+    static const int default_places[] =
+    {
+        CSIDL_DESKTOP,
+        CSIDL_MYDOCUMENTS,
+        CSIDL_DRIVES,
+    };
+    unsigned int i;
+    HKEY hkey;
+
+    if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Comdlg32\\Placesbar",
+            &hkey))
+    {
+        for (i = 0; i < ARRAY_SIZE(fodInfos->places); i++)
+        {
+            static const WCHAR placeW[] = {'P','l','a','c','e','%','d',0};
+            WCHAR nameW[8];
+            DWORD value;
+            HRESULT hr;
+            WCHAR *str;
+
+            sprintfW(nameW, placeW, i);
+            if (get_config_key_dword(hkey, nameW, &value))
+            {
+                hr = SHGetSpecialFolderLocation(NULL, value, &fodInfos->places[i]);
+                if (FAILED(hr))
+                    WARN("Unrecognized special folder %u.\n", value);
+            }
+            else if (get_config_key_string(hkey, nameW, &str))
+            {
+                hr = SHParseDisplayName(str, NULL, &fodInfos->places[i], 0, NULL);
+                if (FAILED(hr))
+                    WARN("Failed to parse custom places location, %s.\n", debugstr_w(str));
+                heap_free(str);
+            }
+        }
+
+        /* FIXME: eliminate duplicates. */
+
+        RegCloseKey(hkey);
+        return;
+    }
+
+    for (i = 0; i < ARRAY_SIZE(default_places); i++)
+        SHGetSpecialFolderLocation(NULL, default_places[i], &fodInfos->places[i]);
+}
+
 /***********************************************************************
  *      GetFileName95
  *
@@ -254,14 +362,11 @@ static BOOL BrowseSelectedFolder(HWND hwnd);
  */
 static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
 {
-
     LRESULT lRes;
-    LPVOID template;
+    void *template;
     HRSRC hRes;
     HANDLE hDlgTmpl = 0;
-    HRESULT hr;
-    DWORD dwSize;
-    LPDLGTEMPLATE hDialogTemplate;
+    WORD templateid;
 
     /* test for missing functionality */
     if (fodInfos->ofnInfos->Flags & UNIMPLEMENTED_FLAGS)
@@ -272,42 +377,38 @@ static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
 
     /* Create the dialog from a template */
 
-    if(!(hRes = FindResourceW(COMDLG32_hInstance,MAKEINTRESOURCEW(NEWFILEOPENORD),(LPCWSTR)RT_DIALOG)))
+    if (is_places_bar_enabled(fodInfos))
+        templateid = NEWFILEOPENV2ORD;
+    else
+        templateid = NEWFILEOPENORD;
+
+    if (!(hRes = FindResourceW(COMDLG32_hInstance, MAKEINTRESOURCEW(templateid), (LPCWSTR)RT_DIALOG)))
     {
         COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
         return FALSE;
     }
     if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hRes )) ||
-        !(dwSize = SizeofResource(COMDLG32_hInstance, hRes )) ||
-        !(hDialogTemplate = malloc(dwSize)) ||
         !(template = LockResource( hDlgTmpl )))
     {
         COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
         return FALSE;
     }
 
-    /* Copy the read only resource */
-    memcpy(hDialogTemplate, template, dwSize);
-
     /* msdn: explorer style dialogs permit sizing by default.
      * The OFN_ENABLESIZING flag is only needed when a hook or
-     * custom tmeplate is provided */
+     * custom template is provided */
     if( (fodInfos->ofnInfos->Flags & OFN_EXPLORER) &&
             !(fodInfos->ofnInfos->Flags & ( OFN_ENABLEHOOK | OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE)))
         fodInfos->ofnInfos->Flags |= OFN_ENABLESIZING;
 
     if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
     {
-        hDialogTemplate->style |= WS_SIZEBOX;
         fodInfos->sizedlg.cx = fodInfos->sizedlg.cy = 0;
         fodInfos->initial_size.x = fodInfos->initial_size.y = 0;
     }
-    else
-        hDialogTemplate->style &= ~WS_SIZEBOX;
-
 
     /* old style hook messages */
-    if (IsHooked(fodInfos))
+    if (is_dialog_hooked(fodInfos))
     {
       fodInfos->HookMsg.fileokstring = RegisterWindowMessageW(FILEOKSTRINGW);
       fodInfos->HookMsg.lbselchstring = RegisterWindowMessageW(LBSELCHSTRINGW);
@@ -315,26 +416,21 @@ static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
       fodInfos->HookMsg.sharevistring = RegisterWindowMessageW(SHAREVISTRINGW);
     }
 
-    /* Some shell namespace extensions depend on COM being initialized. */
-    hr = OleInitialize(NULL);
-
     if (fodInfos->unicode)
       lRes = DialogBoxIndirectParamW(COMDLG32_hInstance,
-                                     hDialogTemplate,
+                                     template,
                                      fodInfos->ofnInfos->hwndOwner,
                                      FileOpenDlgProc95,
                                      (LPARAM) fodInfos);
     else
       lRes = DialogBoxIndirectParamA(COMDLG32_hInstance,
-                                     hDialogTemplate,
+                                     template,
                                      fodInfos->ofnInfos->hwndOwner,
                                      FileOpenDlgProc95,
                                      (LPARAM) fodInfos);
-    if (SUCCEEDED(hr))
+    if (fodInfos->ole_initialized)
         OleUninitialize();
 
-    free(hDialogTemplate);
-
     /* Unable to create the dialog */
     if( lRes == -1)
         return FALSE;
@@ -342,222 +438,192 @@ static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
     return lRes;
 }
 
-/***********************************************************************
- *      GetFileDialog95A
- *
- * Call GetFileName95 with this structure and clean the memory.
- *
- * IN  : The OPENFILENAMEA initialisation structure passed to
- *       GetOpenFileNameA win api function (see filedlg.c)
- */
-static BOOL GetFileDialog95A(LPOPENFILENAMEA ofn,UINT iDlgType)
+static WCHAR *heap_strdupAtoW(const char *str)
 {
-  BOOL ret;
-  FileOpenDlgInfos fodInfos;
-  LPSTR lpstrSavDir = NULL;
-  LPWSTR title = NULL;
-  LPWSTR defext = NULL;
-  LPWSTR filter = NULL;
-  LPWSTR customfilter = NULL;
+    WCHAR *ret;
+    INT len;
 
-  /* Initialize CommDlgExtendedError() */
-  COMDLG32_SetCommDlgExtendedError(0);
+    if (!str)
+        return NULL;
 
-  /* Initialize FileOpenDlgInfos structure */
-  ZeroMemory(&fodInfos, sizeof(FileOpenDlgInfos));
+    len = MultiByteToWideChar(CP_ACP, 0, str, -1, 0, 0);
+    ret = heap_alloc(len * sizeof(WCHAR));
+    MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
 
-  /* Pass in the original ofn */
-  fodInfos.ofnInfos = (LPOPENFILENAMEW)ofn;
+    return ret;
+}
 
-  /* save current directory */
-  if (ofn->Flags & OFN_NOCHANGEDIR)
-  {
-     lpstrSavDir = MemAlloc(MAX_PATH);
-     GetCurrentDirectoryA(MAX_PATH, lpstrSavDir);
-  }
+static void init_filedlg_infoW(OPENFILENAMEW *ofn, FileOpenDlgInfos *info)
+{
+    INITCOMMONCONTROLSEX icc;
 
-  fodInfos.unicode = FALSE;
+    /* Initialize ComboBoxEx32 */
+    icc.dwSize = sizeof(icc);
+    icc.dwICC = ICC_USEREX_CLASSES;
+    InitCommonControlsEx(&icc);
 
-  /* convert all the input strings to unicode */
-  if(ofn->lpstrInitialDir)
-  {
-    DWORD len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrInitialDir, -1, NULL, 0 );
-    fodInfos.initdir = MemAlloc((len+1)*sizeof(WCHAR));
-    MultiByteToWideChar( CP_ACP, 0, ofn->lpstrInitialDir, -1, fodInfos.initdir, len);
-  }
-  else
-    fodInfos.initdir = NULL;
+    /* Initialize CommDlgExtendedError() */
+    COMDLG32_SetCommDlgExtendedError(0);
 
-  if(ofn->lpstrFile)
-  {
-    fodInfos.filename = MemAlloc(ofn->nMaxFile*sizeof(WCHAR));
-    MultiByteToWideChar( CP_ACP, 0, ofn->lpstrFile, -1, fodInfos.filename, ofn->nMaxFile);
-  }
-  else
-    fodInfos.filename = NULL;
+    memset(info, 0, sizeof(*info));
 
-  if(ofn->lpstrDefExt)
-  {
-    DWORD len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrDefExt, -1, NULL, 0 );
-    defext = MemAlloc((len+1)*sizeof(WCHAR));
-    MultiByteToWideChar( CP_ACP, 0, ofn->lpstrDefExt, -1, defext, len);
-  }
-  fodInfos.defext = defext;
+    /* Pass in the original ofn */
+    info->ofnInfos = ofn;
 
-  if(ofn->lpstrTitle)
-  {
-    DWORD len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrTitle, -1, NULL, 0 );
-    title = MemAlloc((len+1)*sizeof(WCHAR));
-    MultiByteToWideChar( CP_ACP, 0, ofn->lpstrTitle, -1, title, len);
-  }
-  fodInfos.title = title;
+    info->title = ofn->lpstrTitle;
+    info->defext = ofn->lpstrDefExt;
+    info->filter = ofn->lpstrFilter;
+    info->customfilter = ofn->lpstrCustomFilter;
 
-  if (ofn->lpstrFilter)
-  {
-    LPCSTR s;
-    int n, len;
-
-    /* filter is a list...  title\0ext\0......\0\0 */
-    s = ofn->lpstrFilter;
-    while (*s) s = s+strlen(s)+1;
-    s++;
-    n = s - ofn->lpstrFilter;
-    len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrFilter, n, NULL, 0 );
-    filter = MemAlloc(len*sizeof(WCHAR));
-    MultiByteToWideChar( CP_ACP, 0, ofn->lpstrFilter, n, filter, len );
-  }
-  fodInfos.filter = filter;
+    if (ofn->lpstrFile)
+    {
+        info->filename = heap_alloc(ofn->nMaxFile * sizeof(WCHAR));
+        lstrcpynW(info->filename, ofn->lpstrFile, ofn->nMaxFile);
+    }
 
-  /* convert lpstrCustomFilter */
-  if (ofn->lpstrCustomFilter)
-  {
-    LPCSTR s;
-    int n, len;
-
-    /* customfilter contains a pair of strings...  title\0ext\0 */
-    s = ofn->lpstrCustomFilter;
-    if (*s) s = s+strlen(s)+1;
-    if (*s) s = s+strlen(s)+1;
-    n = s - ofn->lpstrCustomFilter;
-    len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrCustomFilter, n, NULL, 0 );
-    customfilter = MemAlloc(len*sizeof(WCHAR));
-    MultiByteToWideChar( CP_ACP, 0, ofn->lpstrCustomFilter, n, customfilter, len );
-  }
-  fodInfos.customfilter = customfilter;
+    if (ofn->lpstrInitialDir)
+    {
+        DWORD len = ExpandEnvironmentStringsW(ofn->lpstrInitialDir, NULL, 0);
+        if (len)
+        {
+            info->initdir = heap_alloc(len * sizeof(WCHAR));
+            ExpandEnvironmentStringsW(ofn->lpstrInitialDir, info->initdir, len);
+        }
+    }
 
-  /* Initialize the dialog property */
-  fodInfos.DlgInfos.dwDlgProp = 0;
-  fodInfos.DlgInfos.hwndCustomDlg = NULL;
+    info->unicode = TRUE;
+}
 
-  switch(iDlgType)
-  {
-    case OPEN_DIALOG :
-      ret = GetFileName95(&fodInfos);
-      break;
-    case SAVE_DIALOG :
-      fodInfos.DlgInfos.dwDlgProp |= FODPROP_SAVEDLG;
-      ret = GetFileName95(&fodInfos);
-      break;
-    default :
-      ret = 0;
-  }
+static void init_filedlg_infoA(OPENFILENAMEA *ofn, FileOpenDlgInfos *info)
+{
+    OPENFILENAMEW ofnW;
+    int len;
 
-  if (lpstrSavDir)
-  {
-      SetCurrentDirectoryA(lpstrSavDir);
-      MemFree(lpstrSavDir);
-  }
+    ofnW = *(OPENFILENAMEW *)ofn;
 
-  MemFree(title);
-  MemFree(defext);
-  MemFree(filter);
-  MemFree(customfilter);
-  MemFree(fodInfos.initdir);
-  MemFree(fodInfos.filename);
+    ofnW.lpstrInitialDir = heap_strdupAtoW(ofn->lpstrInitialDir);
+    ofnW.lpstrDefExt = heap_strdupAtoW(ofn->lpstrDefExt);
+    ofnW.lpstrTitle = heap_strdupAtoW(ofn->lpstrTitle);
 
-  TRACE("selected file: %s\n",ofn->lpstrFile);
+    if (ofn->lpstrFile)
+    {
+        len = MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFile, ofn->nMaxFile, NULL, 0);
+        ofnW.lpstrFile = heap_alloc(len * sizeof(WCHAR));
+        MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFile, ofn->nMaxFile, ofnW.lpstrFile, len);
+        ofnW.nMaxFile = len;
+    }
 
-  return ret;
+    if (ofn->lpstrFilter)
+    {
+        LPCSTR s;
+        int n;
+
+        /* filter is a list...  title\0ext\0......\0\0 */
+        s = ofn->lpstrFilter;
+        while (*s) s = s+strlen(s)+1;
+        s++;
+        n = s - ofn->lpstrFilter;
+        len = MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFilter, n, NULL, 0);
+        ofnW.lpstrFilter = heap_alloc(len * sizeof(WCHAR));
+        MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFilter, n, (WCHAR *)ofnW.lpstrFilter, len);
+    }
+
+    /* convert lpstrCustomFilter */
+    if (ofn->lpstrCustomFilter)
+    {
+        int n, len;
+        LPCSTR s;
+
+        /* customfilter contains a pair of strings...  title\0ext\0 */
+        s = ofn->lpstrCustomFilter;
+        if (*s) s = s+strlen(s)+1;
+        if (*s) s = s+strlen(s)+1;
+        n = s - ofn->lpstrCustomFilter;
+        len = MultiByteToWideChar(CP_ACP, 0, ofn->lpstrCustomFilter, n, NULL, 0);
+        ofnW.lpstrCustomFilter = heap_alloc(len * sizeof(WCHAR));
+        MultiByteToWideChar(CP_ACP, 0, ofn->lpstrCustomFilter, n, ofnW.lpstrCustomFilter, len);
+    }
+
+    init_filedlg_infoW(&ofnW, info);
+
+    /* fixup A-specific fields */
+    info->ofnInfos = (OPENFILENAMEW *)ofn;
+    info->unicode = FALSE;
+
+    /* free what was duplicated */
+    heap_free((void *)ofnW.lpstrInitialDir);
+    heap_free(ofnW.lpstrFile);
 }
 
 /***********************************************************************
- *      GetFileDialog95W
+ *      GetFileDialog95
  *
- * Copy the OPENFILENAMEW structure in a FileOpenDlgInfos structure.
  * Call GetFileName95 with this structure and clean the memory.
- *
  */
-static BOOL GetFileDialog95W(LPOPENFILENAMEW ofn,UINT iDlgType)
+static BOOL GetFileDialog95(FileOpenDlgInfos *info, UINT dlg_type)
 {
-  BOOL ret;
-  FileOpenDlgInfos fodInfos;
-  LPWSTR lpstrSavDir = NULL;
-
-  /* Initialize CommDlgExtendedError() */
-  COMDLG32_SetCommDlgExtendedError(0);
-
-  /* Initialize FileOpenDlgInfos structure */
-  ZeroMemory(&fodInfos, sizeof(FileOpenDlgInfos));
+    WCHAR *current_dir = NULL;
+    unsigned int i;
+    BOOL ret;
 
-  /*  Pass in the original ofn */
-  fodInfos.ofnInfos = ofn;
-
-  fodInfos.title = ofn->lpstrTitle;
-  fodInfos.defext = ofn->lpstrDefExt;
-  fodInfos.filter = ofn->lpstrFilter;
-  fodInfos.customfilter = ofn->lpstrCustomFilter;
+    /* save current directory */
+    if (info->ofnInfos->Flags & OFN_NOCHANGEDIR)
+    {
+        current_dir = heap_alloc(MAX_PATH * sizeof(WCHAR));
+        GetCurrentDirectoryW(MAX_PATH, current_dir);
+    }
 
-  /* convert string arguments, save others */
-  if(ofn->lpstrFile)
-  {
-    fodInfos.filename = MemAlloc(ofn->nMaxFile*sizeof(WCHAR));
-    lstrcpynW(fodInfos.filename,ofn->lpstrFile,ofn->nMaxFile);
-  }
-  else
-    fodInfos.filename = NULL;
+    switch (dlg_type)
+    {
+    case OPEN_DIALOG:
+        ret = GetFileName95(info);
+        break;
+    case SAVE_DIALOG:
+        info->DlgInfos.dwDlgProp |= FODPROP_SAVEDLG;
+        ret = GetFileName95(info);
+        break;
+    default:
+        ret = FALSE;
+    }
 
-  if(ofn->lpstrInitialDir)
-  {
-    /* fodInfos.initdir = strdupW(ofn->lpstrInitialDir); */
-    DWORD len = lstrlenW(ofn->lpstrInitialDir)+1;
-    fodInfos.initdir = MemAlloc(len*sizeof(WCHAR));
-    memcpy(fodInfos.initdir,ofn->lpstrInitialDir,len*sizeof(WCHAR));
-  }
-  else
-    fodInfos.initdir = NULL;
+    /* set the lpstrFileTitle */
+    if (ret && info->ofnInfos->lpstrFile && info->ofnInfos->lpstrFileTitle)
+    {
+        if (info->unicode)
+        {
+            LPOPENFILENAMEW ofn = info->ofnInfos;
+            WCHAR *file_title = PathFindFileNameW(ofn->lpstrFile);
+            lstrcpynW(ofn->lpstrFileTitle, file_title, ofn->nMaxFileTitle);
+        }
+        else
+        {
+            LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)info->ofnInfos;
+            char *file_title = PathFindFileNameA(ofn->lpstrFile);
+            lstrcpynA(ofn->lpstrFileTitle, file_title, ofn->nMaxFileTitle);
+        }
+    }
 
-  /* save current directory */
-  if (ofn->Flags & OFN_NOCHANGEDIR)
-  {
-     lpstrSavDir = MemAlloc(MAX_PATH*sizeof(WCHAR));
-     GetCurrentDirectoryW(MAX_PATH, lpstrSavDir);
-  }
+    if (current_dir)
+    {
+        SetCurrentDirectoryW(current_dir);
+        heap_free(current_dir);
+    }
 
-  fodInfos.unicode = TRUE;
+    if (!info->unicode)
+    {
+        heap_free((void *)info->defext);
+        heap_free((void *)info->title);
+        heap_free((void *)info->filter);
+        heap_free((void *)info->customfilter);
+    }
 
-  switch(iDlgType)
-  {
-  case OPEN_DIALOG :
-      ret = GetFileName95(&fodInfos);
-      break;
-  case SAVE_DIALOG :
-      fodInfos.DlgInfos.dwDlgProp |= FODPROP_SAVEDLG;
-      ret = GetFileName95(&fodInfos);
-      break;
-  default :
-      ret = 0;
-  }
+    heap_free(info->filename);
+    heap_free(info->initdir);
 
-  if (lpstrSavDir)
-  {
-      SetCurrentDirectoryW(lpstrSavDir);
-      MemFree(lpstrSavDir);
-  }
+    for (i = 0; i < ARRAY_SIZE(info->places); i++)
+        ILFree(info->places[i]);
 
-  /* restore saved IN arguments and convert OUT arguments back */
-  MemFree(fodInfos.filename);
-  MemFree(fodInfos.initdir);
-  return ret;
+    return ret;
 }
 
 /******************************************************************************
@@ -599,7 +665,7 @@ void COMDLG32_GetCanonicalPath(PCIDLIST_ABSOLUTE pidlAbsCurrent,
   }
   PathAddBackslashW(lpstrPathAndFile);
 
-  TRACE("current directory=%s\n", debugstr_w(lpstrPathAndFile));
+  TRACE("current directory=%s, file=%s\n", debugstr_w(lpstrPathAndFile), debugstr_w(lpstrFile));
 
   /* if the user specified a fully qualified path use it */
   if(PathIsRelativeW(lpstrFile))
@@ -634,7 +700,7 @@ int COMDLG32_SplitFileNames(LPWSTR lpstrEdit, UINT nStrLen, LPWSTR *lpstrFileLis
 
        /* we might get single filename without any '"',
         * so we need nStrLen + terminating \0 + end-of-list \0 */
-       *lpstrFileList = MemAlloc( (nStrLen+2)*sizeof(WCHAR) );
+       *lpstrFileList = heap_alloc((nStrLen + 2) * sizeof(WCHAR));
        *sizeUsed = 0;
 
        /* build delimited file list from filenames */
@@ -643,7 +709,7 @@ int COMDLG32_SplitFileNames(LPWSTR lpstrEdit, UINT nStrLen, LPWSTR *lpstrFileLis
          if ( lpstrEdit[nStrCharCount]=='"' )
          {
            nStrCharCount++;
-           while ((lpstrEdit[nStrCharCount]!='"') && (nStrCharCount <= nStrLen))
+           while ((nStrCharCount <= nStrLen) && (lpstrEdit[nStrCharCount]!='"'))
            {
              (*lpstrFileList)[nFileIndex++] = lpstrEdit[nStrCharCount];
              nStrCharCount++;
@@ -835,7 +901,7 @@ static HWND CreateTemplateDialog(FileOpenDlgInfos *fodInfos, HWND hwnd)
     HANDLE hDlgTmpl = 0;
     HWND hChildDlg = 0;
 
-    TRACE("\n");
+    TRACE("%p, %p\n", fodInfos, hwnd);
 
     /*
      * If OFN_ENABLETEMPLATEHANDLE is specified, the OPENFILENAME
@@ -881,15 +947,15 @@ static HWND CreateTemplateDialog(FileOpenDlgInfos *fodInfos, HWND hwnd)
       }
       if (fodInfos->unicode)
           hChildDlg = CreateDialogIndirectParamW(hinst, template, hwnd,
-              IsHooked(fodInfos) ? (DLGPROC)fodInfos->ofnInfos->lpfnHook : FileOpenDlgProcUserTemplate,
+              is_dialog_hooked(fodInfos) ? (DLGPROC)fodInfos->ofnInfos->lpfnHook : FileOpenDlgProcUserTemplate,
               (LPARAM)fodInfos->ofnInfos);
       else
           hChildDlg = CreateDialogIndirectParamA(hinst, template, hwnd,
-              IsHooked(fodInfos) ? (DLGPROC)fodInfos->ofnInfos->lpfnHook : FileOpenDlgProcUserTemplate,
+              is_dialog_hooked(fodInfos) ? (DLGPROC)fodInfos->ofnInfos->lpfnHook : FileOpenDlgProcUserTemplate,
               (LPARAM)fodInfos->ofnInfos);
       return hChildDlg;
     }
-    else if( IsHooked(fodInfos))
+    else if (is_dialog_hooked(fodInfos))
     {
       RECT rectHwnd;
       struct  {
@@ -922,39 +988,30 @@ static HWND CreateTemplateDialog(FileOpenDlgInfos *fodInfos, HWND hwnd)
 
 LRESULT SendCustomDlgNotificationMessage(HWND hwndParentDlg, UINT uCode)
 {
-    LRESULT hook_result = 0;
-    FileOpenDlgInfos *fodInfos = GetPropA(hwndParentDlg,FileOpenDlgInfosStr);
+    FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwndParentDlg);
+    LRESULT hook_result;
+    OFNOTIFYW ofnNotify;
 
-    TRACE("%p 0x%04x\n",hwndParentDlg, uCode);
+    TRACE("%p %d\n", hwndParentDlg, uCode);
 
-    if(!fodInfos) return 0;
+    if (!fodInfos || !fodInfos->DlgInfos.hwndCustomDlg)
+        return 0;
+
+    TRACE("CALL NOTIFY for %d\n", uCode);
+
+    ofnNotify.hdr.hwndFrom = hwndParentDlg;
+    ofnNotify.hdr.idFrom = 0;
+    ofnNotify.hdr.code = uCode;
+    ofnNotify.lpOFN = fodInfos->ofnInfos;
+    ofnNotify.pszFile = NULL;
+
+    if (fodInfos->unicode)
+        hook_result = SendMessageW(fodInfos->DlgInfos.hwndCustomDlg, WM_NOTIFY, 0, (LPARAM)&ofnNotify);
+    else
+        hook_result = SendMessageA(fodInfos->DlgInfos.hwndCustomDlg, WM_NOTIFY, 0, (LPARAM)&ofnNotify);
+
+    TRACE("RET NOTIFY retval %#lx\n", hook_result);
 
-    if(fodInfos->DlgInfos.hwndCustomDlg)
-    {
-       TRACE("CALL NOTIFY for %x\n", uCode);
-        if(fodInfos->unicode)
-        {
-            OFNOTIFYW ofnNotify;
-            ofnNotify.hdr.hwndFrom=hwndParentDlg;
-            ofnNotify.hdr.idFrom=0;
-            ofnNotify.hdr.code = uCode;
-            ofnNotify.lpOFN = fodInfos->ofnInfos;
-            ofnNotify.pszFile = NULL;
-            hook_result = SendMessageW(fodInfos->DlgInfos.hwndCustomDlg,WM_NOTIFY,0,(LPARAM)&ofnNotify);
-        }
-        else
-        {
-            OFNOTIFYA ofnNotify;
-            ofnNotify.hdr.hwndFrom=hwndParentDlg;
-            ofnNotify.hdr.idFrom=0;
-            ofnNotify.hdr.code = uCode;
-            ofnNotify.lpOFN = (LPOPENFILENAMEA)fodInfos->ofnInfos;
-            ofnNotify.pszFile = NULL;
-            hook_result = SendMessageA(fodInfos->DlgInfos.hwndCustomDlg,WM_NOTIFY,0,(LPARAM)&ofnNotify);
-        }
-       TRACE("RET NOTIFY\n");
-    }
-    TRACE("Retval: 0x%08lx\n", hook_result);
     return hook_result;
 }
 
@@ -962,7 +1019,7 @@ static INT_PTR FILEDLG95_Handle_GetFilePath(HWND hwnd, DWORD size, LPVOID result
 {
     UINT len, total;
     WCHAR *p, *buffer;
-    FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+    FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
 
     TRACE("CDM_GETFILEPATH:\n");
 
@@ -971,7 +1028,7 @@ static INT_PTR FILEDLG95_Handle_GetFilePath(HWND hwnd, DWORD size, LPVOID result
 
     /* get path and filenames */
     len = SendMessageW( fodInfos->DlgInfos.hwndFileName, WM_GETTEXTLENGTH, 0, 0 );
-    buffer = HeapAlloc( GetProcessHeap(), 0, (len + 2 + MAX_PATH) * sizeof(WCHAR) );
+    buffer = heap_alloc( (len + 2 + MAX_PATH) * sizeof(WCHAR) );
     COMDLG32_GetDisplayNameOf( fodInfos->ShellInfos.pidlAbsCurrent, buffer );
     if (len)
     {
@@ -991,7 +1048,7 @@ static INT_PTR FILEDLG95_Handle_GetFilePath(HWND hwnd, DWORD size, LPVOID result
         if (total <= size) WideCharToMultiByte( CP_ACP, 0, buffer, -1, result, size, NULL, NULL );
         TRACE( "CDM_GETFILEPATH: returning %u %s\n", total, debugstr_a(result));
     }
-    HeapFree( GetProcessHeap(), 0, buffer );
+    heap_free( buffer );
     return total;
 }
 
@@ -1002,7 +1059,7 @@ static INT_PTR FILEDLG95_Handle_GetFilePath(HWND hwnd, DWORD size, LPVOID result
 */
 static INT_PTR FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-    FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+    FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
     WCHAR lpstrPath[MAX_PATH];
     INT_PTR retval;
 
@@ -1029,7 +1086,7 @@ static INT_PTR FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM
             break;
 
         case CDM_GETFOLDERIDLIST:
-            retval = COMDLG32_PIDL_ILGetSize(fodInfos->ShellInfos.pidlAbsCurrent);
+            retval = ILGetSize(fodInfos->ShellInfos.pidlAbsCurrent);
             if (retval <= wParam)
                 memcpy((void*)lParam, fodInfos->ShellInfos.pidlAbsCurrent, retval);
             break;
@@ -1085,7 +1142,7 @@ static INT_PTR FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM
  */
 static LRESULT FILEDLG95_OnWMGetMMI( HWND hwnd, LPMINMAXINFO mmiptr)
 {
-    FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+    FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
     if( !(fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)) return FALSE;
     if( fodInfos->initial_size.x || fodInfos->initial_size.y)
     {
@@ -1113,11 +1170,11 @@ static LRESULT FILEDLG95_OnWMSize(HWND hwnd, WPARAM wParam)
     FileOpenDlgInfos *fodInfos;
 
     if( wParam != SIZE_RESTORED) return FALSE;
-    fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+    fodInfos = get_filedlg_infoptr(hwnd);
     if( !(fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)) return FALSE;
     /* get the new dialog rectangle */
     GetWindowRect( hwnd, &rc);
-    TRACE("Size from %d,%d to %d,%d\n", fodInfos->sizedlg.cx, fodInfos->sizedlg.cy,
+    TRACE("%p, size from %d,%d to %d,%d\n", hwnd, fodInfos->sizedlg.cx, fodInfos->sizedlg.cy,
             rc.right -rc.left, rc.bottom -rc.top);
     /* not initialized yet */
     if( (fodInfos->sizedlg.cx == 0 && fodInfos->sizedlg.cy == 0) ||
@@ -1154,8 +1211,9 @@ static LRESULT FILEDLG95_OnWMSize(HWND hwnd, WPARAM wParam)
              * move to bottom */
             switch( ctrlid)
             {
-                /* file name box and file types combo change also width */
+                /* file name (edit or comboboxex) and file types combo change also width */
                 case edt1:
+                case cmb13:
                 case cmb1:
                     DeferWindowPos( hdwp, ctrl, NULL, rc.left, rc.top + chgy,
                             rc.right - rc.left + chgx, rc.bottom - rc.top,
@@ -1209,6 +1267,10 @@ static LRESULT FILEDLG95_OnWMSize(HWND hwnd, WPARAM wParam)
                             rc.bottom - rc.top + chgy,
                             SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
                     break;
+                case IDC_TOOLBARPLACES:
+                    DeferWindowPos( hdwp, ctrl, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top + chgy,
+                                    SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
+                    break;
             }
         }
     }
@@ -1269,15 +1331,41 @@ INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
          int gripx = GetSystemMetrics( SM_CYHSCROLL);
          int gripy = GetSystemMetrics( SM_CYVSCROLL);
 
-        /* Adds the FileOpenDlgInfos in the property list of the dialog
-            so it will be easily accessible through a GetPropA(...) */
-         SetPropA(hwnd, FileOpenDlgInfosStr, fodInfos);
+         /* Some shell namespace extensions depend on COM being initialized. */
+         if (SUCCEEDED(OleInitialize(NULL)))
+             fodInfos->ole_initialized = TRUE;
+
+         SetPropW(hwnd, filedlg_info_propnameW, fodInfos);
 
          FILEDLG95_InitControls(hwnd);
 
          if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
          {
-             GetWindowRect( hwnd, &rc);
+             DWORD style = GetWindowLongW(hwnd, GWL_STYLE);
+             DWORD ex_style = GetWindowLongW(hwnd, GWL_EXSTYLE);
+             RECT client, client_adjusted;
+
+             if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
+             {
+                 style |= WS_SIZEBOX;
+                 ex_style |= WS_EX_WINDOWEDGE;
+             }
+             else
+                 style &= ~WS_SIZEBOX;
+             SetWindowLongW(hwnd, GWL_STYLE, style);
+             SetWindowLongW(hwnd, GWL_EXSTYLE, ex_style);
+
+             GetClientRect( hwnd, &client );
+             GetClientRect( hwnd, &client_adjusted );
+             AdjustWindowRectEx( &client_adjusted, style, FALSE, ex_style );
+
+             GetWindowRect( hwnd, &rc );
+             rc.right += client_adjusted.right - client.right;
+             rc.bottom += client_adjusted.bottom - client.bottom;
+             SetWindowPos(hwnd, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_FRAMECHANGED | SWP_NOACTIVATE |
+                 SWP_NOZORDER | SWP_NOMOVE);
+
+             GetWindowRect( hwnd, &rc );
              fodInfos->DlgInfos.hwndGrip =
                  CreateWindowExA( 0, "SCROLLBAR", NULL,
                      WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS |
@@ -1357,12 +1445,26 @@ INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
 
     case WM_DESTROY:
       {
-          FileOpenDlgInfos * fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+          FileOpenDlgInfos * fodInfos = get_filedlg_infoptr(hwnd);
+          HWND places_bar = GetDlgItem(hwnd, IDC_TOOLBARPLACES);
+          HIMAGELIST himl;
+
           if (fodInfos && fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
               MemDialogSize = fodInfos->sizedlg;
-          RemovePropA(hwnd, FileOpenDlgInfosStr);
+
+          if (places_bar)
+          {
+              himl = (HIMAGELIST)SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_GETIMAGELIST, 0, 0);
+              SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETIMAGELIST, 0, 0);
+              ImageList_Destroy(himl);
+          }
           return FALSE;
       }
+
+    case WM_NCDESTROY:
+        RemovePropW(hwnd, filedlg_info_propnameW);
+        return 0;
+
     case WM_NOTIFY:
     {
        LPNMHDR lpnmh = (LPNMHDR)lParam;
@@ -1409,6 +1511,12 @@ INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
   }
 }
 
+static inline BOOL filename_is_edit( const FileOpenDlgInfos *info )
+{
+    return (info->ofnInfos->lStructSize == OPENFILENAME_SIZE_VERSION_400W) &&
+        (info->ofnInfos->Flags & (OFN_ENABLEHOOK | OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE));
+}
+
 /***********************************************************************
  *      FILEDLG95_InitControls
  *
@@ -1416,9 +1524,9 @@ INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
  */
 static LRESULT FILEDLG95_InitControls(HWND hwnd)
 {
-  int win2000plus = 0;
-  int win98plus   = 0;
-  int handledPath = FALSE;
+  BOOL win2000plus = FALSE;
+  BOOL win98plus   = FALSE;
+  BOOL handledPath = FALSE;
   OSVERSIONINFOW osVi;
   static const WCHAR szwSlash[] = { '\\', 0 };
   static const WCHAR szwStar[] = { '*',0 };
@@ -1441,10 +1549,10 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
   RECT rectlook;
 
   HIMAGELIST toolbarImageList;
-  SHFILEINFOA shFileInfo;
   ITEMIDLIST *desktopPidl;
+  SHFILEINFOW fileinfo;
 
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
 
   TRACE("%p\n", fodInfos);
 
@@ -1459,8 +1567,20 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
   }
   TRACE("Running on 2000+ %d, 98+ %d\n", win2000plus, win98plus);
 
+
+  /* Use either the edit or the comboboxex for the filename control */
+  if (filename_is_edit( fodInfos ))
+  {
+      DestroyWindow( GetDlgItem( hwnd, cmb13 ) );
+      fodInfos->DlgInfos.hwndFileName = GetDlgItem( hwnd, edt1 );
+  }
+  else
+  {
+      DestroyWindow( GetDlgItem( hwnd, edt1 ) );
+      fodInfos->DlgInfos.hwndFileName = GetDlgItem( hwnd, cmb13 );
+  }
+
   /* Get the hwnd of the controls */
-  fodInfos->DlgInfos.hwndFileName = GetDlgItem(hwnd,IDC_FILENAME);
   fodInfos->DlgInfos.hwndFileTypeCB = GetDlgItem(hwnd,IDC_FILETYPE);
   fodInfos->DlgInfos.hwndLookInCB = GetDlgItem(hwnd,IDC_LOOKIN);
 
@@ -1478,13 +1598,13 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
 
   if (fodInfos->unicode)
       fodInfos->DlgInfos.hwndTB = CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL,
-          WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | CCS_NODIVIDER | CCS_NORESIZE,
+          WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | CCS_NODIVIDER | CCS_NORESIZE,
           rectTB.left, rectTB.top,
           rectTB.right - rectTB.left, rectTB.bottom - rectTB.top,
           hwnd, (HMENU)IDC_TOOLBAR, COMDLG32_hInstance, NULL);
   else
       fodInfos->DlgInfos.hwndTB = CreateWindowExA(0, TOOLBARCLASSNAMEA, NULL,
-          WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | CCS_NODIVIDER | CCS_NORESIZE,
+          WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | CCS_NODIVIDER | CCS_NORESIZE,
           rectTB.left, rectTB.top,
           rectTB.right - rectTB.left, rectTB.bottom - rectTB.top,
           hwnd, (HMENU)IDC_TOOLBAR, COMDLG32_hInstance, NULL);
@@ -1499,17 +1619,57 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
   /* Retrieve and add desktop icon to the toolbar */
   toolbarImageList = (HIMAGELIST)SendMessageW(fodInfos->DlgInfos.hwndTB, TB_GETIMAGELIST, 0, 0L);
   SHGetSpecialFolderLocation(hwnd, CSIDL_DESKTOP, &desktopPidl);
-  SHGetFileInfoA((LPCSTR)desktopPidl, 0, &shFileInfo, sizeof(shFileInfo),
+  SHGetFileInfoW((const WCHAR *)desktopPidl, 0, &fileinfo, sizeof(fileinfo),
     SHGFI_PIDL | SHGFI_ICON | SHGFI_SMALLICON);
-  ImageList_AddIcon(toolbarImageList, shFileInfo.hIcon);
+  ImageList_AddIcon(toolbarImageList, fileinfo.hIcon);
 
-  DestroyIcon(shFileInfo.hIcon);
+  DestroyIcon(fileinfo.hIcon);
   CoTaskMemFree(desktopPidl);
 
   /* Finish Toolbar Construction */
   SendMessageW(fodInfos->DlgInfos.hwndTB, TB_ADDBUTTONSW, 9, (LPARAM) tbb);
   SendMessageW(fodInfos->DlgInfos.hwndTB, TB_AUTOSIZE, 0, 0);
 
+  if (is_places_bar_enabled(fodInfos))
+  {
+      TBBUTTON tb = { 0 };
+      HIMAGELIST himl;
+      RECT rect;
+      int i, cx;
+
+      SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_BUTTONSTRUCTSIZE, 0, 0);
+      GetClientRect(GetDlgItem(hwnd, IDC_TOOLBARPLACES), &rect);
+      cx = rect.right - rect.left;
+
+      SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETBUTTONWIDTH, 0, MAKELPARAM(cx, cx));
+      himl = ImageList_Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), ILC_COLOR32, 4, 1);
+
+      filedlg_collect_places_pidls(fodInfos);
+      for (i = 0; i < ARRAY_SIZE(fodInfos->places); i++)
+      {
+          int index;
+
+          if (!fodInfos->places[i])
+              continue;
+
+          memset(&fileinfo, 0, sizeof(fileinfo));
+          SHGetFileInfoW((const WCHAR *)fodInfos->places[i], 0, &fileinfo, sizeof(fileinfo),
+              SHGFI_PIDL | SHGFI_DISPLAYNAME | SHGFI_ICON);
+          index = ImageList_AddIcon(himl, fileinfo.hIcon);
+
+          tb.iBitmap = index;
+          tb.iString = (INT_PTR)fileinfo.szDisplayName;
+          tb.fsState = TBSTATE_ENABLED | TBSTATE_WRAP;
+          tb.idCommand = TBPLACES_CMDID_PLACE0 + i;
+          SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_ADDBUTTONSW, 1, (LPARAM)&tb);
+
+          DestroyIcon(fileinfo.hIcon);
+      }
+
+      SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETIMAGELIST, 0, (LPARAM)himl);
+      SendDlgItemMessageW(hwnd, IDC_TOOLBARPLACES, TB_SETBUTTONSIZE, 0, MAKELPARAM(cx, cx * 3 / 4));
+  }
+
   /* Set the window text with the text specified in the OPENFILENAME structure */
   if(fodInfos->title)
   {
@@ -1518,7 +1678,7 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
   else if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
   {
       WCHAR buf[64];
-      LoadStringW(COMDLG32_hInstance, IDS_SAVE_AS, buf, sizeof(buf)/sizeof(WCHAR));
+      LoadStringW(COMDLG32_hInstance, IDS_SAVE_AS, buf, ARRAY_SIZE(buf));
       SetWindowTextW(hwnd, buf);
   }
 
@@ -1538,67 +1698,87 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
          result = GetFullPathNameW(fodInfos->filename, MAX_PATH, tmpBuf, &nameBit);
          if (result) {
 
-            /* nameBit is always shorter than the original filename */
-            lstrcpyW(fodInfos->filename,nameBit);
+            /* nameBit is always shorter than the original filename. It may be NULL
+             * when the filename contains only a drive name instead of file name */
+            if (nameBit)
+            {
+                lstrcpyW(fodInfos->filename,nameBit);
+                *nameBit = 0x00;
+            }
+            else
+                *fodInfos->filename = '\0';
 
-            *nameBit = 0x00;
-            MemFree(fodInfos->initdir);
-            fodInfos->initdir = MemAlloc((lstrlenW(tmpBuf) + 1)*sizeof(WCHAR));
+            heap_free(fodInfos->initdir);
+            fodInfos->initdir = heap_alloc((lstrlenW(tmpBuf) + 1)*sizeof(WCHAR));
             lstrcpyW(fodInfos->initdir, tmpBuf);
             handledPath = TRUE;
             TRACE("Value in Filename includes path, overriding InitialDir: %s, %s\n",
                     debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
          }
-         SetDlgItemTextW(hwnd, IDC_FILENAME, fodInfos->filename);
+         SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename );
 
       } else {
-         SetDlgItemTextW(hwnd, IDC_FILENAME, fodInfos->filename);
+         SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename );
       }
   }
 
   /* 2. (All platforms) If initdir is not null, then use it */
-  if ((handledPath == FALSE) && (fodInfos->initdir!=NULL) &&
-                                (*fodInfos->initdir!=0x00))
+  if (!handledPath && fodInfos->initdir && *fodInfos->initdir)
   {
-      /* Work out the proper path as supplied one might be relative          */
-      /* (Here because supplying '.' as dir browses to My Computer)          */
-      if (handledPath==FALSE) {
-          WCHAR tmpBuf[MAX_PATH];
-          WCHAR tmpBuf2[MAX_PATH];
-          WCHAR *nameBit;
-          DWORD result;
-
-          lstrcpyW(tmpBuf, fodInfos->initdir);
-          if( PathFileExistsW(tmpBuf) ) {
-              /* initdir does not have to be a directory. If a file is
-               * specified, the dir part is taken */
-              if( PathIsDirectoryW(tmpBuf)) {
-                  if (tmpBuf[lstrlenW(tmpBuf)-1] != '\\') {
-                     lstrcatW(tmpBuf, szwSlash);
-                  }
-                  lstrcatW(tmpBuf, szwStar);
-              }
-              result = GetFullPathNameW(tmpBuf, MAX_PATH, tmpBuf2, &nameBit);
-              if (result) {
-                 *nameBit = 0x00;
-                 MemFree(fodInfos->initdir);
-                 fodInfos->initdir = MemAlloc((lstrlenW(tmpBuf2) + 1)*sizeof(WCHAR));
-                 lstrcpyW(fodInfos->initdir, tmpBuf2);
-                 handledPath = TRUE;
-                 TRACE("Value in InitDir changed to %s\n", debugstr_w(fodInfos->initdir));
-              }
-          }
-          else if (fodInfos->initdir)
-          {
-                    MemFree(fodInfos->initdir);
-                    fodInfos->initdir = NULL;
-                    TRACE("Value in InitDir is not an existing path, changed to (nil)\n");
+        /* Work out the proper path as supplied one might be relative          */
+        /* (Here because supplying '.' as dir browses to My Computer)          */
+        WCHAR tmpBuf[MAX_PATH];
+        WCHAR tmpBuf2[MAX_PATH];
+        WCHAR *nameBit;
+        DWORD result;
+
+        lstrcpyW(tmpBuf, fodInfos->initdir);
+        if (PathFileExistsW(tmpBuf)) {
+            /* initdir does not have to be a directory. If a file is
+             * specified, the dir part is taken */
+            if (PathIsDirectoryW(tmpBuf)) {
+                PathAddBackslashW(tmpBuf);
+                lstrcatW(tmpBuf, szwStar);
+            }
+            result = GetFullPathNameW(tmpBuf, MAX_PATH, tmpBuf2, &nameBit);
+            if (result) {
+                *nameBit = 0x00;
+                heap_free(fodInfos->initdir);
+                fodInfos->initdir = heap_alloc((lstrlenW(tmpBuf2) + 1) * sizeof(WCHAR));
+                lstrcpyW(fodInfos->initdir, tmpBuf2);
+                handledPath = TRUE;
+                TRACE("Value in InitDir changed to %s\n", debugstr_w(fodInfos->initdir));
+            }
+        }
+        else if (fodInfos->initdir)
+        {
+            heap_free(fodInfos->initdir);
+            fodInfos->initdir = NULL;
+            TRACE("Value in InitDir is not an existing path, changed to (nil)\n");
+        }
+  }
+
+#ifdef __REACTOS__
+  if (!handledPath && (!fodInfos->initdir || !*fodInfos->initdir))
+  {
+      /* 2.5. Win2000+: Recently used defext */
+      if (win2000plus) {
+          fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
+          fodInfos->initdir[0] = '\0';
+
+          FILEDLG95_MRU_load_ext(fodInfos->initdir, MAX_PATH, fodInfos->defext);
+
+          if (fodInfos->initdir[0] && PathIsDirectoryW(fodInfos->initdir)) {
+             handledPath = TRUE;
+          } else {
+             heap_free(fodInfos->initdir);
+             fodInfos->initdir = NULL;
           }
       }
   }
+#endif
 
-  if ((handledPath == FALSE) && ((fodInfos->initdir==NULL) ||
-                                 (*fodInfos->initdir==0x00)))
+  if (!handledPath && (!fodInfos->initdir || !*fodInfos->initdir))
   {
       /* 3. All except w2k+: if filename contains a path use it */
       if (!win2000plus && fodInfos->filename &&
@@ -1618,20 +1798,20 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
             *nameBit = 0x00;
 
             len = lstrlenW(tmpBuf);
-            MemFree(fodInfos->initdir);
-            fodInfos->initdir = MemAlloc((len+1)*sizeof(WCHAR));
+            heap_free(fodInfos->initdir);
+            fodInfos->initdir = heap_alloc((len+1)*sizeof(WCHAR));
             lstrcpyW(fodInfos->initdir, tmpBuf);
 
             handledPath = TRUE;
             TRACE("Value in Filename includes path, overriding initdir: %s, %s\n",
                  debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
          }
-         SetDlgItemTextW(hwnd, IDC_FILENAME, fodInfos->filename);
+         SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename );
       }
 
       /* 4. Win2000+: Recently used */
-      if (handledPath == FALSE && win2000plus) {
-          fodInfos->initdir = MemAlloc(MAX_PATH * sizeof(WCHAR));
+      if (!handledPath && win2000plus) {
+          fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
           fodInfos->initdir[0] = '\0';
 
           FILEDLG95_MRU_load_filename(fodInfos->initdir);
@@ -1639,15 +1819,14 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
           if (fodInfos->initdir[0] && PathFileExistsW(fodInfos->initdir)){
              handledPath = TRUE;
           }else{
-             MemFree(fodInfos->initdir);
+             heap_free(fodInfos->initdir);
              fodInfos->initdir = NULL;
           }
       }
 
       /* 5. win98+ and win2000+ if any files of specified filter types in
             current directory, use it                                      */
-      if ( win98plus && handledPath == FALSE &&
-           fodInfos->filter && *fodInfos->filter) {
+      if (win98plus && !handledPath && fodInfos->filter && *fodInfos->filter) {
 
          LPCWSTR lpstrPos = fodInfos->filter;
          WIN32_FIND_DATAW FindFileData;
@@ -1672,8 +1851,8 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
 
            } else {
 
-               MemFree(fodInfos->initdir);
-               fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR));
+               heap_free(fodInfos->initdir);
+               fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
                GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir);
 
                handledPath = TRUE;
@@ -1686,31 +1865,32 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
       }
 
       /* 6. Win98+ and 2000+: Use personal files dir, others use current dir */
-      if (handledPath == FALSE && (win2000plus || win98plus)) {
-          fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR));
+      if (!handledPath && (win2000plus || win98plus)) {
+          fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
 
-          if(!COMDLG32_SHGetFolderPathW(hwnd, CSIDL_PERSONAL, 0, 0, fodInfos->initdir))
+          if (SHGetFolderPathW(hwnd, CSIDL_PERSONAL, 0, 0, fodInfos->initdir) == S_OK)
           {
-            if(!COMDLG32_SHGetFolderPathW(hwnd, CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE, 0, 0, fodInfos->initdir))
-            {
-                /* last fallback */
-                GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir);
-                TRACE("No personal or desktop dir, using cwd as failsafe: %s\n", debugstr_w(fodInfos->initdir));
-            } else {
+              if (SHGetFolderPathW(hwnd, CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE, 0, 0, fodInfos->initdir) == S_OK)
+              {
+                  /* last fallback */
+                  GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir);
+                  TRACE("No personal or desktop dir, using cwd as failsafe: %s\n", debugstr_w(fodInfos->initdir));
+              }
+              else
                 TRACE("No personal dir, using desktop instead: %s\n", debugstr_w(fodInfos->initdir));
-            }
-          } else {
-            TRACE("No initial dir specified, using personal files dir of %s\n", debugstr_w(fodInfos->initdir));
           }
+          else
+              TRACE("No initial dir specified, using personal files dir of %s\n", debugstr_w(fodInfos->initdir));
+
           handledPath = TRUE;
-      } else if (handledPath==FALSE) {
-          fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR));
+      } else if (!handledPath) {
+          fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
           GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir);
           handledPath = TRUE;
           TRACE("No initial dir specified, using current dir of %s\n", debugstr_w(fodInfos->initdir));
       }
   }
-  SetFocus(GetDlgItem(hwnd, IDC_FILENAME));
+  SetFocus( fodInfos->DlgInfos.hwndFileName );
   TRACE("After manipulation, file = %s, dir = %s\n", debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
 
   /* Must the open as read only check box be checked ?*/
@@ -1720,7 +1900,7 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
   }
 
   /* Must the open as read only check box be hidden? */
-  if(fodInfos->ofnInfos->Flags & OFN_HIDEREADONLY)
+  if (filedialog_is_readonly_hidden(fodInfos))
   {
     ShowWindow(GetDlgItem(hwnd,IDC_OPENREADONLY),SW_HIDE);
     EnableWindow(GetDlgItem(hwnd, IDC_OPENREADONLY), FALSE);
@@ -1737,9 +1917,9 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
   if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
   {
       WCHAR buf[16];
-      LoadStringW(COMDLG32_hInstance, IDS_SAVE_BUTTON, buf, sizeof(buf)/sizeof(WCHAR));
+      LoadStringW(COMDLG32_hInstance, IDS_SAVE_BUTTON, buf, ARRAY_SIZE(buf));
       SetDlgItemTextW(hwnd, IDOK, buf);
-      LoadStringW(COMDLG32_hInstance, IDS_SAVE_IN, buf, sizeof(buf)/sizeof(WCHAR));
+      LoadStringW(COMDLG32_hInstance, IDS_SAVE_IN, buf, ARRAY_SIZE(buf));
       SetDlgItemTextW(hwnd, IDC_LOOKINSTATIC, buf);
   }
 
@@ -1764,7 +1944,7 @@ static LRESULT FILEDLG95_ResizeControls(HWND hwnd, WPARAM wParam, LPARAM lParam)
     UINT flags = SWP_NOACTIVATE;
 
     ArrangeCtrlPositions(fodInfos->DlgInfos.hwndCustomDlg, hwnd,
-        (fodInfos->ofnInfos->Flags & (OFN_HIDEREADONLY | OFN_SHOWHELP)) == OFN_HIDEREADONLY);
+        filedialog_is_readonly_hidden(fodInfos) && !(fodInfos->ofnInfos->Flags & OFN_SHOWHELP));
 
     /* resize the custom dialog to the parent size */
     if (fodInfos->ofnInfos->Flags & (OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE))
@@ -1777,15 +1957,15 @@ static LRESULT FILEDLG95_ResizeControls(HWND hwnd, WPARAM wParam, LPARAM lParam)
       flags |= SWP_NOSIZE;
       SetRectEmpty(&rc);
     }
-      SetWindowPos(fodInfos->DlgInfos.hwndCustomDlg, HWND_BOTTOM,
-          0, 0, rc.right, rc.bottom, flags);
+    SetWindowPos(fodInfos->DlgInfos.hwndCustomDlg, HWND_BOTTOM,
+                 0, 0, rc.right, rc.bottom, flags);
   }
   else
   {
-    /* Resize the height, if open as read only checkbox ad help button are
+    /* Resize the height; if opened as read-only, checkbox and help button are
      * hidden and we are not using a custom template nor a customDialog
      */
-    if ( (fodInfos->ofnInfos->Flags & OFN_HIDEREADONLY) &&
+    if (filedialog_is_readonly_hidden(fodInfos) &&
                 (!(fodInfos->ofnInfos->Flags &
                    (OFN_SHOWHELP|OFN_ENABLETEMPLATE|OFN_ENABLETEMPLATEHANDLE))))
     {
@@ -1837,8 +2017,7 @@ static LRESULT FILEDLG95_FillControls(HWND hwnd, WPARAM wParam, LPARAM lParam)
   /* Browse to the initial directory */
   IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,pidlItemId, SBSP_ABSOLUTE);
 
-  /* Free pidlItem memory */
-  COMDLG32_SHFree(pidlItemId);
+  ILFree(pidlItemId);
 
   return TRUE;
 }
@@ -1853,6 +2032,20 @@ void FILEDLG95_Clean(HWND hwnd)
       FILEDLG95_LOOKIN_Clean(hwnd);
       FILEDLG95_SHELL_Clean(hwnd);
 }
+
+
+/***********************************************************************
+ * Browse to arbitrary pidl
+ */
+static void filedlg_browse_to_pidl(const FileOpenDlgInfos *info, LPITEMIDLIST pidl)
+{
+    TRACE("%p, %p\n", info->ShellInfos.hwndOwner, pidl);
+
+    IShellBrowser_BrowseObject(info->Shell.FOIShellBrowser, pidl, SBSP_ABSOLUTE);
+    if (info->ofnInfos->Flags & OFN_EXPLORER)
+        SendCustomDlgNotificationMessage(info->ShellInfos.hwndOwner, CDN_FOLDERCHANGE);
+}
+
 /***********************************************************************
  *      FILEDLG95_OnWMCommand
  *
@@ -1860,11 +2053,11 @@ void FILEDLG95_Clean(HWND hwnd)
  */
 static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam)
 {
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
   WORD wNotifyCode = HIWORD(wParam); /* notification code */
-  WORD wID = LOWORD(wParam);         /* item, control, or accelerator identifier */
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+  WORD id = LOWORD(wParam);         /* item, control, or accelerator identifier */
 
-  switch(wID)
+  switch (id)
   {
     /* OK button */
   case IDOK:
@@ -1901,12 +2094,28 @@ static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam)
   case FCIDM_TB_REPORTVIEW:
     FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWDETAILSA);
     break;
-    /* Details option button */
+
   case FCIDM_TB_DESKTOP:
-    FILEDLG95_SHELL_BrowseToDesktop(hwnd);
+  {
+    LPITEMIDLIST pidl;
+
+    SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, &pidl);
+    filedlg_browse_to_pidl(fodInfos, pidl);
+    ILFree(pidl);
+    break;
+  }
+
+  /* Places bar */
+  case TBPLACES_CMDID_PLACE0:
+  case TBPLACES_CMDID_PLACE1:
+  case TBPLACES_CMDID_PLACE2:
+  case TBPLACES_CMDID_PLACE3:
+  case TBPLACES_CMDID_PLACE4:
+    filedlg_browse_to_pidl(fodInfos, fodInfos->places[id - TBPLACES_CMDID_PLACE0]);
     break;
 
-  case IDC_FILENAME:
+  case edt1:
+  case cmb13:
     break;
 
   }
@@ -1922,7 +2131,7 @@ static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam)
  */
 static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd)
 {
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
 
   TRACE("\n");
 
@@ -1944,7 +2153,7 @@ static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd)
 static BOOL FILEDLG95_SendFileOK( HWND hwnd, FileOpenDlgInfos *fodInfos )
 {
     /* ask the hook if we can close */
-    if(IsHooked(fodInfos))
+    if (is_dialog_hooked(fodInfos))
     {
         LRESULT retval = 0;
 
@@ -1980,9 +2189,9 @@ static BOOL FILEDLG95_SendFileOK( HWND hwnd, FileOpenDlgInfos *fodInfos )
  */
 BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPWSTR lpstrFileList, UINT nFileCount, UINT sizeUsed)
 {
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
   WCHAR   lpstrPathSpec[MAX_PATH] = {0};
   UINT   nCount, nSizePath;
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
   TRACE("\n");
 
@@ -2032,7 +2241,7 @@ BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPWSTR lpstrFileList, UINT nFileCo
 
       /* move to the next file in the list of files */
       lpstrTemp += lstrlenW(lpstrTemp) + 1;
-      COMDLG32_SHFree(pidl);
+      ILFree(pidl);
     }
   }
 
@@ -2170,7 +2379,8 @@ static void FILEDLG95_MRU_save_filename(LPCWSTR filename)
     HKEY hkey;
 
     /* get the current executable's name */
-    if(!GetModuleFileNameW(GetModuleHandleW(NULL), module_path, sizeof(module_path)/sizeof(module_path[0]))) {
+    if (!GetModuleFileNameW(GetModuleHandleW(NULL), module_path, ARRAY_SIZE(module_path)))
+    {
         WARN("GotModuleFileName failed: %d\n", GetLastError());
         return;
     }
@@ -2195,7 +2405,7 @@ static void FILEDLG95_MRU_save_filename(LPCWSTR filename)
 
         final_len = path_len + lstrlenW(module_name) + 2;
 
-        final = MemAlloc(final_len * sizeof(WCHAR));
+        final = heap_alloc(final_len * sizeof(WCHAR));
         if(!final)
             return;
         lstrcpyW(final, module_name);
@@ -2206,12 +2416,12 @@ static void FILEDLG95_MRU_save_filename(LPCWSTR filename)
                 final_len * sizeof(WCHAR));
         if(ret){
             WARN("Error saving MRU data to slot %s: %d\n", wine_dbgstr_w(slot_name), ret);
-            MemFree(final);
+            heap_free(final);
             RegCloseKey(hkey);
             return;
         }
 
-        MemFree(final);
+        heap_free(final);
     }
 
     { /* update MRUList value */
@@ -2251,35 +2461,276 @@ static void FILEDLG95_MRU_save_filename(LPCWSTR filename)
     }
 }
 
-/* load the most-recently-used path for this module */
-static void FILEDLG95_MRU_load_filename(LPWSTR stored_path)
+/* load the most-recently-used path for this module */
+static void FILEDLG95_MRU_load_filename(LPWSTR stored_path)
+{
+    WCHAR module_path[MAX_PATH], *module_name;
+
+    /* get the current executable's name */
+    if (!GetModuleFileNameW(GetModuleHandleW(NULL), module_path, ARRAY_SIZE(module_path)))
+    {
+        WARN("GotModuleFileName failed: %d\n", GetLastError());
+        return;
+    }
+    module_name = strrchrW(module_path, '\\');
+    if(!module_name)
+        module_name = module_path;
+    else
+        module_name += 1;
+
+    FILEDLG95_MRU_get_slot(module_name, stored_path, NULL);
+    TRACE("got MRU path: %s\n", wine_dbgstr_w(stored_path));
+}
+#ifdef __REACTOS__
+static const WCHAR s_subkey[] =
+{
+    'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
+    'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s',
+    'i','o','n','\\','E','x','p','l','o','r','e','r','\\','C','o','m','D','l','g',
+    '3','2','\\','O','p','e','n','S','a','v','e','M','R','U',0
+};
+static const WCHAR s_szAst[] = { '*', 0 };
+
+typedef INT (CALLBACK *MRUStringCmpFnW)(LPCWSTR lhs, LPCWSTR rhs);
+typedef INT (CALLBACK *MRUBinaryCmpFn)(LPCVOID lhs, LPCVOID rhs, DWORD length);
+
+/* https://docs.microsoft.com/en-us/windows/desktop/shell/mruinfo */
+typedef struct tagMRUINFOW
+{
+    DWORD   cbSize;
+    UINT    uMax;
+    UINT    fFlags;
+    HKEY    hKey;
+    LPCWSTR lpszSubKey;
+    union
+    {
+        MRUStringCmpFnW string_cmpfn;
+        MRUBinaryCmpFn  binary_cmpfn;
+    } u;
+} MRUINFOW, *LPMRUINFOW;
+
+/* flags for MRUINFOW.fFlags */
+#define MRU_STRING 0x0000
+#define MRU_BINARY 0x0001
+#define MRU_CACHEWRITE 0x0002
+
+static HINSTANCE s_hComCtl32 = NULL;
+
+/* comctl32.400: CreateMRUListW */
+typedef HANDLE (WINAPI *CREATEMRULISTW)(const MRUINFOW *);
+static CREATEMRULISTW s_pCreateMRUListW = NULL;
+
+/* comctl32.401: AddMRUStringW */
+typedef INT (WINAPI *ADDMRUSTRINGW)(HANDLE, LPCWSTR);
+static ADDMRUSTRINGW s_pAddMRUStringW = NULL;
+
+/* comctl32.402: FindMRUStringW */
+typedef INT (WINAPI *FINDMRUSTRINGW)(HANDLE, LPCWSTR, LPINT);
+static FINDMRUSTRINGW s_pFindMRUStringW = NULL;
+
+/* comctl32.403: EnumMRUListW */
+typedef INT (WINAPI *ENUMMRULISTW)(HANDLE, INT, LPVOID, DWORD);
+static ENUMMRULISTW s_pEnumMRUListW = NULL;
+
+/* comctl32.152: FreeMRUList */
+typedef void (WINAPI *FREEMRULIST)(HANDLE);
+static FREEMRULIST s_pFreeMRUList = NULL;
+
+static BOOL FILEDLG_InitMRUList(void)
+{
+    if (s_hComCtl32)
+        return TRUE;
+
+    s_hComCtl32 = GetModuleHandleA("comctl32");
+    if (!s_hComCtl32)
+        return FALSE;
+
+    s_pCreateMRUListW = (CREATEMRULISTW)GetProcAddress(s_hComCtl32, (LPCSTR)400);
+    s_pAddMRUStringW = (ADDMRUSTRINGW)GetProcAddress(s_hComCtl32, (LPCSTR)401);
+    s_pFindMRUStringW = (FINDMRUSTRINGW)GetProcAddress(s_hComCtl32, (LPCSTR)402);
+    s_pEnumMRUListW = (ENUMMRULISTW)GetProcAddress(s_hComCtl32, (LPCSTR)403);
+    s_pFreeMRUList = (FREEMRULIST)GetProcAddress(s_hComCtl32, (LPCSTR)152);
+    if (!s_pCreateMRUListW ||
+        !s_pAddMRUStringW ||
+        !s_pFindMRUStringW ||
+        !s_pEnumMRUListW ||
+        !s_pFreeMRUList)
+    {
+        s_hComCtl32 = NULL;
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static BOOL ExtIsPicture(LPCWSTR ext)
+{
+    static const WCHAR s_image_exts[][6] =
+    {
+        { 'b','m','p',0 },
+        { 'd','i','b',0 },
+        { 'j','p','g',0 },
+        { 'j','p','e','g',0 },
+        { 'j','p','e',0 },
+        { 'j','f','i','f',0 },
+        { 'p','n','g',0 },
+        { 'g','i','f',0 },
+        { 't','i','f',0 },
+        { 't','i','f','f',0 }
+    };
+    size_t i;
+
+    for (i = 0; i < ARRAY_SIZE(s_image_exts); ++i)
+    {
+        if (lstrcmpiW(ext, s_image_exts[i]) == 0)
+        {
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+static void FILEDLG95_MRU_load_ext(LPWSTR stored_path, size_t cchMax, LPCWSTR defext)
+{
+    HKEY hOpenSaveMRT = NULL;
+    LONG result;
+    MRUINFOW mi;
+    HANDLE hList;
+    WCHAR szText[MAX_PATH];
+    INT ret = 0;
+
+    stored_path[0] = 0;
+
+    if (!defext || !*defext || !FILEDLG_InitMRUList())
+    {
+        return;
+    }
+
+    if (*defext == '.')
+        ++defext;
+
+    result = RegOpenKeyW(HKEY_CURRENT_USER, s_subkey, &hOpenSaveMRT);
+    if (!result && hOpenSaveMRT)
+    {
+        ZeroMemory(&mi, sizeof(mi));
+        mi.cbSize = sizeof(mi);
+        mi.uMax = 26;
+        mi.fFlags = MRU_STRING;
+        mi.hKey = hOpenSaveMRT;
+        mi.lpszSubKey = defext;
+        mi.u.string_cmpfn = lstrcmpiW;
+        hList = (*s_pCreateMRUListW)(&mi);
+        if (hList)
+        {
+            ret = (*s_pEnumMRUListW)(hList, 0, szText, sizeof(szText));
+            if (ret > 0)
+            {
+                lstrcpynW(stored_path, szText, cchMax);
+                PathRemoveFileSpecW(stored_path);
+            }
+            (*s_pFreeMRUList)(hList);
+        }
+
+        if (stored_path[0] == 0)
+        {
+            mi.cbSize = sizeof(mi);
+            mi.uMax = 26;
+            mi.fFlags = MRU_STRING;
+            mi.hKey = hOpenSaveMRT;
+            mi.lpszSubKey = s_szAst;
+            mi.u.string_cmpfn = lstrcmpiW;
+            hList = (*s_pCreateMRUListW)(&mi);
+            if (hList)
+            {
+                ret = (*s_pEnumMRUListW)(hList, 0, szText, sizeof(szText));
+                if (ret > 0)
+                {
+                    lstrcpynW(stored_path, szText, cchMax);
+                    PathRemoveFileSpecW(stored_path);
+                }
+                (*s_pFreeMRUList)(hList);
+            }
+        }
+
+        RegCloseKey(hOpenSaveMRT);
+    }
+
+    if (stored_path[0] == 0)
+    {
+        LPITEMIDLIST pidl;
+        if (ExtIsPicture(defext))
+        {
+            SHGetSpecialFolderLocation(NULL, CSIDL_MYPICTURES, &pidl);
+        }
+        else
+        {
+            SHGetSpecialFolderLocation(NULL, CSIDL_MYDOCUMENTS, &pidl);
+        }
+        SHGetPathFromIDListW(pidl, stored_path);
+        ILFree(pidl);
+    }
+}
+
+static void FILEDLG95_MRU_save_ext(LPCWSTR filename)
 {
-    WCHAR module_path[MAX_PATH], *module_name;
+    HKEY hOpenSaveMRT = NULL;
+    LONG result;
+    MRUINFOW mi;
+    HANDLE hList;
+    LPCWSTR defext = PathFindExtensionW(filename);
 
-    /* get the current executable's name */
-    if(!GetModuleFileNameW(GetModuleHandleW(NULL), module_path, sizeof(module_path)/sizeof(module_path[0]))) {
-        WARN("GotModuleFileName failed: %d\n", GetLastError());
+    if (!defext || !*defext || !FILEDLG_InitMRUList())
+    {
         return;
     }
-    module_name = strrchrW(module_path, '\\');
-    if(!module_name)
-        module_name = module_path;
-    else
-        module_name += 1;
 
-    FILEDLG95_MRU_get_slot(module_name, stored_path, NULL);
-    TRACE("got MRU path: %s\n", wine_dbgstr_w(stored_path));
+    if (*defext == '.')
+        ++defext;
+
+    result = RegOpenKeyW(HKEY_CURRENT_USER, s_subkey, &hOpenSaveMRT);
+    if (!result && hOpenSaveMRT)
+    {
+        ZeroMemory(&mi, sizeof(mi));
+        mi.cbSize = sizeof(mi);
+        mi.uMax = 26;
+        mi.fFlags = MRU_STRING;
+        mi.hKey = hOpenSaveMRT;
+        mi.lpszSubKey = defext;
+        mi.u.string_cmpfn = lstrcmpiW;
+        hList = (*s_pCreateMRUListW)(&mi);
+        if (hList)
+        {
+            (*s_pAddMRUStringW)(hList, filename);
+            (*s_pFreeMRUList)(hList);
+        }
+
+        mi.cbSize = sizeof(mi);
+        mi.uMax = 26;
+        mi.fFlags = MRU_STRING;
+        mi.hKey = hOpenSaveMRT;
+        mi.lpszSubKey = s_szAst;
+        mi.u.string_cmpfn = lstrcmpiW;
+        hList = (*s_pCreateMRUListW)(&mi);
+        if (hList)
+        {
+            (*s_pAddMRUStringW)(hList, filename);
+            (*s_pFreeMRUList)(hList);
+        }
+
+        RegCloseKey(hOpenSaveMRT);
+    }
 }
+#endif
 
 void FILEDLG95_OnOpenMessage(HWND hwnd, int idCaption, int idText)
 {
   WCHAR strMsgTitle[MAX_PATH];
   WCHAR strMsgText [MAX_PATH];
   if (idCaption)
-    LoadStringW(COMDLG32_hInstance, idCaption, strMsgTitle, sizeof(strMsgTitle)/sizeof(WCHAR));
+    LoadStringW(COMDLG32_hInstance, idCaption, strMsgTitle, ARRAY_SIZE(strMsgTitle));
   else
     strMsgTitle[0] = '\0';
-  LoadStringW(COMDLG32_hInstance, idText, strMsgText, sizeof(strMsgText)/sizeof(WCHAR));
+  LoadStringW(COMDLG32_hInstance, idText, strMsgText, ARRAY_SIZE(strMsgText));
   MessageBoxW(hwnd,strMsgText, strMsgTitle, MB_OK | MB_ICONHAND);
 }
 
@@ -2363,7 +2814,7 @@ int FILEDLG95_ValidatePathAction(LPWSTR lpstrPathAndFile, IShellFolder **ppsf,
                 nOpenAction = ONOPEN_OPEN;
                 break;
             }
-            COMDLG32_SHFree(pidl);
+            ILFree(pidl);
             pidl = NULL;
         }
         else if (!(flags & OFN_NOVALIDATE))
@@ -2395,7 +2846,7 @@ int FILEDLG95_ValidatePathAction(LPWSTR lpstrPathAndFile, IShellFolder **ppsf,
             break;
         }
     }
-    if(pidl) COMDLG32_SHFree(pidl);
+    ILFree(pidl);
 
     return nOpenAction;
 }
@@ -2409,6 +2860,7 @@ int FILEDLG95_ValidatePathAction(LPWSTR lpstrPathAndFile, IShellFolder **ppsf,
  */
 BOOL FILEDLG95_OnOpen(HWND hwnd)
 {
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
   LPWSTR lpstrFileList;
   UINT nFileCount = 0;
   UINT sizeUsed = 0;
@@ -2416,7 +2868,6 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
   WCHAR lpstrPathAndFile[MAX_PATH];
   LPSHELLFOLDER lpsf = NULL;
   int nOpenAction;
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
   TRACE("hwnd=%p\n", hwnd);
 
@@ -2448,7 +2899,7 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
 */
 
   COMDLG32_GetCanonicalPath(fodInfos->ShellInfos.pidlAbsCurrent, lpstrFileList, lpstrPathAndFile);
-  MemFree(lpstrFileList);
+  heap_free(lpstrFileList);
 
 /*
   Step 2: here we have a cleaned up path
@@ -2495,14 +2946,14 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
         DWORD len;
 
         /* replace the current filter */
-        MemFree(fodInfos->ShellInfos.lpstrCurrentFilter);
+        heap_free(fodInfos->ShellInfos.lpstrCurrentFilter);
         len = lstrlenW(lpszTemp)+1;
-        fodInfos->ShellInfos.lpstrCurrentFilter = MemAlloc(len * sizeof(WCHAR));
+        fodInfos->ShellInfos.lpstrCurrentFilter = heap_alloc(len * sizeof(WCHAR));
         lstrcpyW( fodInfos->ShellInfos.lpstrCurrentFilter, lpszTemp);
 
         /* set the filter cb to the extension when possible */
         if(-1 < (iPos = FILEDLG95_FILETYPE_SearchExt(fodInfos->DlgInfos.hwndFileTypeCB, lpszTemp)))
-        CBSetCurSel(fodInfos->DlgInfos.hwndFileTypeCB, iPos);
+        SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETCURSEL, iPos, 0);
       }
       /* fall through */
     case ONOPEN_BROWSE:   /* browse to the highest folder we could bind to */
@@ -2514,12 +2965,13 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
           LPITEMIDLIST pidlCurrent;
           IPersistFolder2_GetCurFolder(ppf2, &pidlCurrent);
           IPersistFolder2_Release(ppf2);
-         if( ! COMDLG32_PIDL_ILIsEqual(pidlCurrent, fodInfos->ShellInfos.pidlAbsCurrent))
+          if (!ILIsEqual(pidlCurrent, fodInfos->ShellInfos.pidlAbsCurrent))
          {
             if (SUCCEEDED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser, pidlCurrent, SBSP_ABSOLUTE))
                 && fodInfos->ofnInfos->Flags & OFN_EXPLORER)
             {
               SendCustomDlgNotificationMessage(hwnd, CDN_FOLDERCHANGE);
+              SendMessageA(fodInfos->DlgInfos.hwndFileName, WM_SETTEXT, 0, (LPARAM)"");
             }
          }
          else if( nOpenAction == ONOPEN_SEARCH )
@@ -2527,8 +2979,16 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
             if (fodInfos->Shell.FOIShellView)
               IShellView_Refresh(fodInfos->Shell.FOIShellView);
          }
-          COMDLG32_SHFree(pidlCurrent);
-          SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1);
+          ILFree(pidlCurrent);
+          if (filename_is_edit( fodInfos ))
+              SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1);
+          else
+          {
+              HWND hwnd;
+
+              hwnd = (HWND)SendMessageA(fodInfos->DlgInfos.hwndFileName, CBEM_GETEDITCONTROL, 0, 0);
+              SendMessageW(hwnd, EM_SETSEL, 0, -1);
+          }
         }
       }
       ret = FALSE;
@@ -2546,12 +3006,12 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
 
         /* Attach the file extension with file name*/
         ext = PathFindExtensionW(lpstrPathAndFile);
-        if (! *ext)
+        if (! *ext && fodInfos->defext)
         {
             /* if no extension is specified with file name, then */
             /* attach the extension from file filter or default one */
             
-            const WCHAR *filterExt = NULL;
+            WCHAR *filterExt = NULL;
             LPWSTR lpstrFilter = NULL;
             static const WCHAR szwDot[] = {'.',0};
             int PathLength = lstrlenW(lpstrPathAndFile);
@@ -2561,36 +3021,63 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
                                              fodInfos->ofnInfos->nFilterIndex-1);
 
             if (lpstrFilter != (LPWSTR)CB_ERR)  /* control is not empty */
-                filterExt = PathFindExtensionW(lpstrFilter);
+            {
+                WCHAR* filterSearchIndex;
+                filterExt = heap_alloc((lstrlenW(lpstrFilter) + 1) * sizeof(WCHAR));
+                strcpyW(filterExt, lpstrFilter);
+
+                /* if a semicolon-separated list of file extensions was given, do not include the
+                   semicolon or anything after it in the extension.
+                   example: if filterExt was "*.abc;*.def", it will become "*.abc" */
+                filterSearchIndex = strchrW(filterExt, ';');
+                if (filterSearchIndex)
+                {
+                    filterSearchIndex[0] = '\0';
+                }
+
+                /* find the file extension by searching for the first dot in filterExt */
+                /* strip the * or anything else from the extension, "*.abc" becomes "abc" */
+                /* if the extension is invalid or contains a glob, ignore it */
+                filterSearchIndex = strchrW(filterExt, '.');
+                if (filterSearchIndex++ && !strchrW(filterSearchIndex, '*') && !strchrW(filterSearchIndex, '?'))
+                {
+                    strcpyW(filterExt, filterSearchIndex);
+                }
+                else
+                {
+                    heap_free(filterExt);
+                    filterExt = NULL;
+                }
+            }
 
-            if ( filterExt && *filterExt ) /* attach the file extension from file type filter*/
-                filterExt = filterExt + 1;
-            else if ( fodInfos->defext ) /* attach the default file extension*/
-                filterExt = fodInfos->defext;
+            if (!filterExt)
+            {
+                /* use the default file extension */
+                filterExt = heap_alloc((lstrlenW(fodInfos->defext) + 1) * sizeof(WCHAR));
+                strcpyW(filterExt, fodInfos->defext);
+            }
 
-            /* If extension contains a glob, ignore it */
-            if ( filterExt && !strchrW(filterExt, '*') && !strchrW(filterExt, '?') )
+            if (*filterExt) /* ignore filterExt="" */
             {
                 /* Attach the dot*/
                 lstrcatW(lpstrPathAndFile, szwDot);
                 /* Attach the extension */
-                lstrcatW(lpstrPathAndFile, filterExt );
+                lstrcatW(lpstrPathAndFile, filterExt);
             }
 
+            heap_free(filterExt);
+
             /* In Open dialog: if file does not exist try without extension */
             if (!(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG) && !PathFileExistsW(lpstrPathAndFile))
                   lpstrPathAndFile[PathLength] = '\0';
-        }
 
-       if (fodInfos->defext) /* add default extension */
-       {
-         /* Set/clear the output OFN_EXTENSIONDIFFERENT flag */
-         if (*ext)
-           ext++;
-         if (!lstrcmpiW(fodInfos->defext, ext))
-           fodInfos->ofnInfos->Flags &= ~OFN_EXTENSIONDIFFERENT;
-         else
-           fodInfos->ofnInfos->Flags |= OFN_EXTENSIONDIFFERENT;
+            /* Set/clear the output OFN_EXTENSIONDIFFERENT flag */
+            if (*ext)
+                ext++;
+            if (!lstrcmpiW(fodInfos->defext, ext))
+                fodInfos->ofnInfos->Flags &= ~OFN_EXTENSIONDIFFERENT;
+            else
+                fodInfos->ofnInfos->Flags |= OFN_EXTENSIONDIFFERENT;
        }
 
        /* In Save dialog: check if the file already exists */
@@ -2671,35 +3158,22 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
           }
           else
           {
-               LPSTR lpszTemp;
-               LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)fodInfos->ofnInfos;
+              LPSTR lpszTemp;
+              CHAR tempFileA[MAX_PATH];
+
+              /* avoid using fodInfos->ofnInfos->lpstrFile since it can be NULL */
+              WideCharToMultiByte(CP_ACP, 0, lpstrPathAndFile, -1,
+                                  tempFileA, sizeof(tempFileA), NULL, NULL);
 
               /* set filename offset */
-              lpszTemp = PathFindFileNameA(ofn->lpstrFile);
-              fodInfos->ofnInfos->nFileOffset = (lpszTemp - ofn->lpstrFile);
+              lpszTemp = PathFindFileNameA(tempFileA);
+              fodInfos->ofnInfos->nFileOffset = (lpszTemp - tempFileA);
 
               /* set extension offset */
-              lpszTemp = PathFindExtensionA(ofn->lpstrFile);
-              fodInfos->ofnInfos->nFileExtension = (*lpszTemp) ? (lpszTemp - ofn->lpstrFile) + 1 : 0;
+              lpszTemp = PathFindExtensionA(tempFileA);
+              fodInfos->ofnInfos->nFileExtension = (*lpszTemp) ? (lpszTemp - tempFileA) + 1 : 0;
           }
 
-          /* set the lpstrFileTitle */
-          if(fodInfos->ofnInfos->lpstrFileTitle)
-         {
-            LPWSTR lpstrFileTitle = PathFindFileNameW(lpstrPathAndFile);
-            if(fodInfos->unicode)
-            {
-              LPOPENFILENAMEW ofn = fodInfos->ofnInfos;
-             lstrcpynW(ofn->lpstrFileTitle, lpstrFileTitle, ofn->nMaxFileTitle);
-            }
-            else
-            {
-              LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)fodInfos->ofnInfos;
-              WideCharToMultiByte(CP_ACP, 0, lpstrFileTitle, -1,
-                    ofn->lpstrFileTitle, ofn->nMaxFileTitle, NULL, NULL);
-            }
-         }
-
           /* copy currently selected filter to lpstrCustomFilter */
           if (fodInfos->ofnInfos->lpstrCustomFilter)
           {
@@ -2720,6 +3194,9 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
              goto ret;
 
           FILEDLG95_MRU_save_filename(lpstrPathAndFile);
+#ifdef __REACTOS__
+          FILEDLG95_MRU_save_ext(lpstrPathAndFile);
+#endif
 
           TRACE("close\n");
          FILEDLG95_Clean(hwnd);
@@ -2733,7 +3210,8 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
           if (fodInfos->ofnInfos->Flags & OFN_ALLOWMULTISELECT)
              size += 1;
           /* return needed size in first two bytes of lpstrFile */
-          *(WORD *)fodInfos->ofnInfos->lpstrFile = size;
+          if(fodInfos->ofnInfos->lpstrFile)
+              *(WORD *)fodInfos->ofnInfos->lpstrFile = size;
           FILEDLG95_Clean(hwnd);
           ret = EndDialog(hwnd, FALSE);
           COMDLG32_SetCommDlgExtendedError(FNERR_BUFFERTOOSMALL);
@@ -2754,9 +3232,9 @@ ret:
  */
 static LRESULT FILEDLG95_SHELL_Init(HWND hwnd)
 {
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
 
-  TRACE("\n");
+  TRACE("%p\n", hwnd);
 
   /*
    * Initialisation of the FileOpenDialogInfos structure
@@ -2789,7 +3267,7 @@ static LRESULT FILEDLG95_SHELL_Init(HWND hwnd)
  */
 static BOOL FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb)
 {
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
   IContextMenu * pcm;
 
   TRACE("(%p,%p)\n", hwnd, lpVerb);
@@ -2820,7 +3298,7 @@ static BOOL FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb)
  */
 static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd)
 {
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
 
   TRACE("\n");
 
@@ -2834,28 +3312,6 @@ static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd)
   }
   return FALSE;
 }
-
-/***********************************************************************
- *      FILEDLG95_SHELL_BrowseToDesktop
- *
- * Browse to the Desktop
- * If the function succeeds, the return value is nonzero.
- */
-static BOOL FILEDLG95_SHELL_BrowseToDesktop(HWND hwnd)
-{
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
-  LPITEMIDLIST pidl;
-  HRESULT hres;
-
-  TRACE("\n");
-
-  SHGetSpecialFolderLocation(0,CSIDL_DESKTOP,&pidl);
-  hres = IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser, pidl, SBSP_ABSOLUTE);
-  if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
-      SendCustomDlgNotificationMessage(hwnd, CDN_FOLDERCHANGE);
-  COMDLG32_SHFree(pidl);
-  return SUCCEEDED(hres);
-}
 /***********************************************************************
  *      FILEDLG95_SHELL_Clean
  *
@@ -2863,11 +3319,11 @@ static BOOL FILEDLG95_SHELL_BrowseToDesktop(HWND hwnd)
  */
 static void FILEDLG95_SHELL_Clean(HWND hwnd)
 {
-    FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+    FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
 
     TRACE("\n");
 
-    COMDLG32_SHFree(fodInfos->ShellInfos.pidlAbsCurrent);
+    ILFree(fodInfos->ShellInfos.pidlAbsCurrent);
 
     /* clean Shell interfaces */
     if (fodInfos->Shell.FOIShellView)
@@ -2875,7 +3331,8 @@ static void FILEDLG95_SHELL_Clean(HWND hwnd)
       IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView);
       IShellView_Release(fodInfos->Shell.FOIShellView);
     }
-    IShellFolder_Release(fodInfos->Shell.FOIShellFolder);
+    if (fodInfos->Shell.FOIShellFolder)
+      IShellFolder_Release(fodInfos->Shell.FOIShellFolder);
     IShellBrowser_Release(fodInfos->Shell.FOIShellBrowser);
     if (fodInfos->Shell.FOIDataObject)
       IDataObject_Release(fodInfos->Shell.FOIDataObject);
@@ -2888,11 +3345,11 @@ static void FILEDLG95_SHELL_Clean(HWND hwnd)
  */
 static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd)
 {
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
   int nFilters = 0;  /* number of filters */
   int nFilterIndexCB;
 
-  TRACE("\n");
+  TRACE("%p\n", hwnd);
 
   if(fodInfos->customfilter)
   {
@@ -2907,12 +3364,13 @@ static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd)
 
       /* Copy the extensions */
       if (! *lpstrPos) return E_FAIL;  /* malformed filter */
-      if (!(lpstrExt = MemAlloc((lstrlenW(lpstrPos)+1)*sizeof(WCHAR)))) return E_FAIL;
+      if (!(lpstrExt = heap_alloc((lstrlenW(lpstrPos)+1)*sizeof(WCHAR)))) return E_FAIL;
       lstrcpyW(lpstrExt,lpstrPos);
 
       /* Add the item at the end of the combo */
-      CBAddString(fodInfos->DlgInfos.hwndFileTypeCB, fodInfos->customfilter);
-      CBSetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB, nFilters, lpstrExt);
+      SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_ADDSTRING, 0, (LPARAM)fodInfos->customfilter);
+      SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETITEMDATA, nFilters, (LPARAM)lpstrExt);
+
       nFilters++;
   }
   if(fodInfos->filter)
@@ -2933,17 +3391,17 @@ static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd)
       lpstrDisplay = lpstrPos;
       lpstrPos += lstrlenW(lpstrPos) + 1;
 
-      CBAddString(fodInfos->DlgInfos.hwndFileTypeCB, lpstrDisplay);
+      SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_ADDSTRING, 0, (LPARAM)lpstrDisplay);
 
       nFilters++;
 
       /* Copy the extensions */
-      if (!(lpstrExt = MemAlloc((lstrlenW(lpstrPos)+1)*sizeof(WCHAR)))) return E_FAIL;
+      if (!(lpstrExt = heap_alloc((lstrlenW(lpstrPos)+1)*sizeof(WCHAR)))) return E_FAIL;
       lstrcpyW(lpstrExt,lpstrPos);
       lpstrPos += lstrlenW(lpstrPos) + 1;
 
       /* Add the item at the end of the combo */
-      CBSetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB, nFilters-1, lpstrExt);
+      SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETITEMDATA, nFilters - 1, (LPARAM)lpstrExt);
 
       /* malformed filters are added anyway... */
       if (!*lpstrExt) break;
@@ -2973,7 +3431,7 @@ static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd)
       nFilterIndexCB--;
 
     /* Set the current index selection. */
-    CBSetCurSel(fodInfos->DlgInfos.hwndFileTypeCB, nFilterIndexCB);
+    SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_SETCURSEL, nFilterIndexCB, 0);
 
     /* Get the corresponding text string from the combo box. */
     lpstrFilter = (LPWSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,
@@ -2987,7 +3445,7 @@ static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd)
       DWORD len;
       CharLowerW(lpstrFilter); /* lowercase */
       len = lstrlenW(lpstrFilter)+1;
-      fodInfos->ShellInfos.lpstrCurrentFilter = MemAlloc( len * sizeof(WCHAR) );
+      fodInfos->ShellInfos.lpstrCurrentFilter = heap_alloc( len * sizeof(WCHAR) );
       lstrcpyW(fodInfos->ShellInfos.lpstrCurrentFilter,lpstrFilter);
     }
   } else
@@ -3003,7 +3461,7 @@ static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd)
  */
 static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode)
 {
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
 
   switch(wNotifyCode)
   {
@@ -3012,14 +3470,14 @@ static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode)
       LPWSTR lpstrFilter;
 
       /* Get the current item of the filetype combo box */
-      int iItem = CBGetCurSel(fodInfos->DlgInfos.hwndFileTypeCB);
+      int iItem = SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_GETCURSEL, 0, 0);
 
       /* set the current filter index */
       fodInfos->ofnInfos->nFilterIndex = iItem +
         (fodInfos->customfilter == NULL ? 1 : 0);
 
       /* Set the current filter with the current selection */
-      MemFree(fodInfos->ShellInfos.lpstrCurrentFilter);
+      heap_free(fodInfos->ShellInfos.lpstrCurrentFilter);
 
       lpstrFilter = (LPWSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,
                                              iItem);
@@ -3028,7 +3486,7 @@ static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode)
           DWORD len;
           CharLowerW(lpstrFilter); /* lowercase */
           len = lstrlenW(lpstrFilter)+1;
-          fodInfos->ShellInfos.lpstrCurrentFilter = MemAlloc( len * sizeof(WCHAR) );
+          fodInfos->ShellInfos.lpstrCurrentFilter = heap_alloc( len * sizeof(WCHAR) );
           lstrcpyW(fodInfos->ShellInfos.lpstrCurrentFilter,lpstrFilter);
           if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
               SendCustomDlgNotificationMessage(hwnd,CDN_TYPECHANGE);
@@ -3048,7 +3506,9 @@ static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode)
  */
 static int FILEDLG95_FILETYPE_SearchExt(HWND hwnd,LPCWSTR lpstrExt)
 {
-  int i, iCount = CBGetCount(hwnd);
+  int i, iCount;
+
+  iCount = SendMessageW(hwnd, CB_GETCOUNT, 0, 0);
 
   TRACE("%s\n", debugstr_w(lpstrExt));
 
@@ -3070,9 +3530,11 @@ static int FILEDLG95_FILETYPE_SearchExt(HWND hwnd,LPCWSTR lpstrExt)
  */
 static void FILEDLG95_FILETYPE_Clean(HWND hwnd)
 {
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
   int iPos;
-  int iCount = CBGetCount(fodInfos->DlgInfos.hwndFileTypeCB);
+  int iCount;
+
+  iCount = SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_GETCOUNT, 0, 0);
 
   TRACE("\n");
 
@@ -3081,13 +3543,12 @@ static void FILEDLG95_FILETYPE_Clean(HWND hwnd)
   {
     for(iPos = iCount-1;iPos>=0;iPos--)
     {
-      MemFree((LPSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,iPos));
-      CBDeleteString(fodInfos->DlgInfos.hwndFileTypeCB,iPos);
+      heap_free((void *)CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,iPos));
+      SendMessageW(fodInfos->DlgInfos.hwndFileTypeCB, CB_DELETESTRING, iPos, 0);
     }
   }
   /* Current filter */
-  MemFree(fodInfos->ShellInfos.lpstrCurrentFilter);
-
+  heap_free(fodInfos->ShellInfos.lpstrCurrentFilter);
 }
 
 /***********************************************************************
@@ -3121,26 +3582,32 @@ static void FILEDLG95_LOOKIN_Init(HWND hwndCombo)
   IShellFolder *psfRoot, *psfDrives;
   IEnumIDList  *lpeRoot, *lpeDrives;
   LPITEMIDLIST pidlDrives, pidlTmp, pidlTmp1, pidlAbsTmp;
+  HDC hdc;
+  TEXTMETRICW tm;
+  LookInInfos *liInfos = heap_alloc_zero(sizeof(*liInfos));
 
-  LookInInfos *liInfos = MemAlloc(sizeof(LookInInfos));
-
-  TRACE("\n");
+  TRACE("%p\n", hwndCombo);
 
   liInfos->iMaxIndentation = 0;
 
   SetPropA(hwndCombo, LookInInfosStr, liInfos);
 
+  hdc = GetDC( hwndCombo );
+  SelectObject( hdc, (HFONT)SendMessageW( hwndCombo, WM_GETFONT, 0, 0 ));
+  GetTextMetricsW( hdc, &tm );
+  ReleaseDC( hwndCombo, hdc );
+
   /* set item height for both text field and listbox */
-  CBSetItemHeight(hwndCombo,-1,GetSystemMetrics(SM_CYSMICON));
-  CBSetItemHeight(hwndCombo,0,GetSystemMetrics(SM_CYSMICON));
-   
+  SendMessageW(hwndCombo, CB_SETITEMHEIGHT, -1, max(tm.tmHeight, GetSystemMetrics(SM_CYSMICON)));
+  SendMessageW(hwndCombo, CB_SETITEMHEIGHT, 0, max(tm.tmHeight, GetSystemMetrics(SM_CYSMICON)));
+
   /* Turn on the extended UI for the combo box like Windows does */
-  CBSetExtendedUI(hwndCombo, TRUE);
+  SendMessageW(hwndCombo, CB_SETEXTENDEDUI, TRUE, 0);
 
   /* Initialise data of Desktop folder */
   SHGetSpecialFolderLocation(0,CSIDL_DESKTOP,&pidlTmp);
   FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlTmp,LISTEND);
-  COMDLG32_SHFree(pidlTmp);
+  ILFree(pidlTmp);
 
   SHGetSpecialFolderLocation(0,CSIDL_DRIVES,&pidlDrives);
 
@@ -3159,7 +3626,7 @@ static void FILEDLG95_LOOKIN_Init(HWND hwndCombo)
        if (!FILEDLG95_unixfs_is_rooted_at_desktop()) 
        {
          /* special handling for CSIDL_DRIVES */
-         if (COMDLG32_PIDL_ILIsEqual(pidlTmp, pidlDrives))
+         if (ILIsEqual(pidlTmp, pidlDrives))
          {
            if(SUCCEEDED(IShellFolder_BindToObject(psfRoot, pidlTmp, NULL, &IID_IShellFolder, (LPVOID*)&psfDrives)))
            {
@@ -3168,10 +3635,10 @@ static void FILEDLG95_LOOKIN_Init(HWND hwndCombo)
              {
                while (S_OK == IEnumIDList_Next(lpeDrives, 1, &pidlTmp1, NULL))
                {
-                 pidlAbsTmp = COMDLG32_PIDL_ILCombine(pidlTmp, pidlTmp1);
+                 pidlAbsTmp = ILCombine(pidlTmp, pidlTmp1);
                  FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlAbsTmp,LISTEND);
-                 COMDLG32_SHFree(pidlAbsTmp);
-                 COMDLG32_SHFree(pidlTmp1);
+                 ILFree(pidlAbsTmp);
+                 ILFree(pidlTmp1);
                }
                IEnumIDList_Release(lpeDrives);
              }
@@ -3180,14 +3647,14 @@ static void FILEDLG95_LOOKIN_Init(HWND hwndCombo)
          }
        }
 
-        COMDLG32_SHFree(pidlTmp);
+        ILFree(pidlTmp);
       }
       IEnumIDList_Release(lpeRoot);
     }
     IShellFolder_Release(psfRoot);
   }
 
-  COMDLG32_SHFree(pidlDrives);
+  ILFree(pidlDrives);
 }
 
 /***********************************************************************
@@ -3207,7 +3674,8 @@ static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct)
   int iIndentation;
   TEXTMETRICW tm;
   LPSFOLDER tmpFolder;
-  LookInInfos *liInfos = GetPropA(pDIStruct->hwndItem,LookInInfosStr);
+  UINT shgfi_flags = SHGFI_PIDL | SHGFI_OPENICON | SHGFI_SYSICONINDEX | SHGFI_DISPLAYNAME;
+  UINT icon_width, icon_height;
 
   TRACE("\n");
 
@@ -3219,27 +3687,18 @@ static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct)
     return 0;
 
 
-  if(pDIStruct->itemID == liInfos->uSelectedItem)
-  {
-    ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
-                                               0,
-                                               &sfi,
-                                               sizeof (sfi),
-                                               SHGFI_PIDL | SHGFI_SMALLICON |
-                                               SHGFI_OPENICON | SHGFI_SYSICONINDEX    |
-                                               SHGFI_DISPLAYNAME );
-  }
-  else
+  icon_width = GetSystemMetrics(SM_CXICON);
+  icon_height = GetSystemMetrics(SM_CYICON);
+  if (pDIStruct->rcItem.bottom - pDIStruct->rcItem.top < icon_height)
   {
-    ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
-                                                  0,
-                                                  &sfi,
-                                                  sizeof (sfi),
-                                                  SHGFI_PIDL | SHGFI_SMALLICON |
-                                                  SHGFI_SYSICONINDEX |
-                                                  SHGFI_DISPLAYNAME);
+      icon_width = GetSystemMetrics(SM_CXSMICON);
+      icon_height = GetSystemMetrics(SM_CYSMICON);
+      shgfi_flags |= SHGFI_SMALLICON;
   }
 
+  ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
+                                             0, &sfi, sizeof (sfi), shgfi_flags );
+
   /* Is this item selected ? */
   if(pDIStruct->itemState & ODS_SELECTED)
   {
@@ -3256,34 +3715,24 @@ static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct)
 
   /* Do not indent item if drawing in the edit of the combo */
   if(pDIStruct->itemState & ODS_COMBOBOXEDIT)
-  {
     iIndentation = 0;
-    ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
-                                                0,
-                                                &sfi,
-                                                sizeof (sfi),
-                                                SHGFI_PIDL | SHGFI_SMALLICON | SHGFI_OPENICON
-                                                | SHGFI_SYSICONINDEX | SHGFI_DISPLAYNAME  );
-
-  }
   else
-  {
     iIndentation = tmpFolder->m_iIndent;
-  }
+
   /* Draw text and icon */
 
   /* Initialise the icon display area */
-  rectIcon.left = pDIStruct->rcItem.left + ICONWIDTH/2 * iIndentation;
-  rectIcon.top = pDIStruct->rcItem.top;
-  rectIcon.right = rectIcon.left + ICONWIDTH;
-  rectIcon.bottom = pDIStruct->rcItem.bottom;
+  rectIcon.left = pDIStruct->rcItem.left + 1 + icon_width/2 * iIndentation;
+  rectIcon.top = (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom - icon_height) / 2;
+  rectIcon.right = rectIcon.left + icon_width + XTEXTOFFSET;
+  rectIcon.bottom = (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom + icon_height) / 2;
 
   /* Initialise the text display area */
   GetTextMetricsW(pDIStruct->hDC, &tm);
   rectText.left = rectIcon.right;
   rectText.top =
          (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom - tm.tmHeight) / 2;
-  rectText.right = pDIStruct->rcItem.right + XTEXTOFFSET;
+  rectText.right = pDIStruct->rcItem.right;
   rectText.bottom =
          (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom + tm.tmHeight) / 2;
 
@@ -3308,7 +3757,7 @@ static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct)
  */
 static BOOL FILEDLG95_LOOKIN_OnCommand(HWND hwnd, WORD wNotifyCode)
 {
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
 
   TRACE("%p\n", fodInfos);
 
@@ -3319,7 +3768,7 @@ static BOOL FILEDLG95_LOOKIN_OnCommand(HWND hwnd, WORD wNotifyCode)
       LPSFOLDER tmpFolder;
       int iItem;
 
-      iItem = CBGetCurSel(fodInfos->DlgInfos.hwndLookInCB);
+      iItem = SendMessageW(fodInfos->DlgInfos.hwndLookInCB, CB_GETCURSEL, 0, 0);
 
       if( iItem == CB_ERR) return FALSE;
 
@@ -3356,7 +3805,7 @@ static int FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId)
   SFOLDER *tmpFolder;
   LookInInfos *liInfos;
 
-  TRACE("%08x\n", iInsertId);
+  TRACE("%p, %p, %d\n", hwnd, pidl, iInsertId);
 
   if(!pidl)
     return -1;
@@ -3364,17 +3813,17 @@ static int FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId)
   if(!(liInfos = GetPropA(hwnd,LookInInfosStr)))
     return -1;
 
-  tmpFolder = MemAlloc(sizeof(SFOLDER));
+  tmpFolder = heap_alloc_zero(sizeof(*tmpFolder));
   tmpFolder->m_iIndent = 0;
 
   /* Calculate the indentation of the item in the lookin*/
   pidlNext = pidl;
-  while( (pidlNext=COMDLG32_PIDL_ILGetNext(pidlNext)) )
+  while ((pidlNext = ILGetNext(pidlNext)))
   {
     tmpFolder->m_iIndent++;
   }
 
-  tmpFolder->pidlItem = COMDLG32_PIDL_ILClone(pidl);
+  tmpFolder->pidlItem = ILClone(pidl);
 
   if(tmpFolder->m_iIndent > liInfos->iMaxIndentation)
     liInfos->iMaxIndentation = tmpFolder->m_iIndent;
@@ -3384,10 +3833,9 @@ static int FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId)
                   0,
                   &sfi,
                   sizeof(sfi),
-                  SHGFI_DISPLAYNAME | SHGFI_SYSICONINDEX
-                  | SHGFI_PIDL | SHGFI_SMALLICON | SHGFI_ATTRIBUTES | SHGFI_ATTR_SPECIFIED);
+                  SHGFI_DISPLAYNAME | SHGFI_PIDL | SHGFI_ATTRIBUTES | SHGFI_ATTR_SPECIFIED);
 
-  TRACE("-- Add %s attr=%08x\n", debugstr_w(sfi.szDisplayName), sfi.dwAttributes);
+  TRACE("-- Add %s attr=0x%08x\n", debugstr_w(sfi.szDisplayName), sfi.dwAttributes);
 
   if((sfi.dwAttributes & SFGAO_FILESYSANCESTOR) || (sfi.dwAttributes & SFGAO_FILESYSTEM))
   {
@@ -3398,20 +3846,20 @@ static int FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId)
     /* Add the item at the end of the list */
     if(iInsertId < 0)
     {
-      iItemID = CBAddString(hwnd,sfi.szDisplayName);
+      iItemID = SendMessageW(hwnd, CB_ADDSTRING, 0, (LPARAM)sfi.szDisplayName);
     }
     /* Insert the item at the iInsertId position*/
     else
     {
-      iItemID = CBInsertString(hwnd,sfi.szDisplayName,iInsertId);
+      iItemID = SendMessageW(hwnd, CB_INSERTSTRING, iInsertId, (LPARAM)sfi.szDisplayName);
     }
 
-    CBSetItemDataPtr(hwnd,iItemID,tmpFolder);
+    SendMessageW(hwnd, CB_SETITEMDATA, iItemID, (LPARAM)tmpFolder);
     return iItemID;
   }
 
-  COMDLG32_SHFree( tmpFolder->pidlItem );
-  MemFree( tmpFolder );
+  ILFree( tmpFolder->pidlItem );
+  heap_free( tmpFolder );
   return -1;
 
 }
@@ -3439,8 +3887,7 @@ static int FILEDLG95_LOOKIN_InsertItemAfterParent(HWND hwnd,LPITEMIDLIST pidl)
     iParentPos = FILEDLG95_LOOKIN_InsertItemAfterParent(hwnd,pidlParent);
   }
 
-  /* Free pidlParent memory */
-  COMDLG32_SHFree(pidlParent);
+  ILFree(pidlParent);
 
   return FILEDLG95_LOOKIN_AddItem(hwnd,pidl,iParentPos + 1);
 }
@@ -3456,7 +3903,7 @@ int FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl)
   int iItemPos;
   LookInInfos *liInfos;
 
-  TRACE("\n");
+  TRACE("%p, %p\n", hwnd, pidl);
 
   iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)pidl,SEARCH_PIDL);
 
@@ -3482,7 +3929,7 @@ int FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl)
     }
   }
 
-  CBSetCurSel(hwnd,iItemPos);
+  SendMessageW(hwnd, CB_SETCURSEL, iItemPos, 0);
   liInfos->uSelectedItem = iItemPos;
 
   return 0;
@@ -3507,9 +3954,9 @@ static int FILEDLG95_LOOKIN_RemoveMostExpandedItem(HWND hwnd)
   if((iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,liInfos->iMaxIndentation,SEARCH_EXP)) >=0)
   {
     SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,iItemPos);
-    COMDLG32_SHFree(tmpFolder->pidlItem);
-    MemFree(tmpFolder);
-    CBDeleteString(hwnd,iItemPos);
+    ILFree(tmpFolder->pidlItem);
+    heap_free(tmpFolder);
+    SendMessageW(hwnd, CB_DELETESTRING, iItemPos, 0);
     liInfos->iMaxIndentation--;
 
     return iItemPos;
@@ -3527,7 +3974,9 @@ static int FILEDLG95_LOOKIN_RemoveMostExpandedItem(HWND hwnd)
 static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMethod)
 {
   int i = 0;
-  int iCount = CBGetCount(hwnd);
+  int iCount;
+
+  iCount = SendMessageW(hwnd, CB_GETCOUNT, 0, 0);
 
   TRACE("0x%08lx 0x%x\n",searchArg, iSearchMethod);
 
@@ -3537,7 +3986,7 @@ static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMet
     {
       LPSFOLDER tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,i);
 
-      if(iSearchMethod == SEARCH_PIDL && COMDLG32_PIDL_ILIsEqual((LPITEMIDLIST)searchArg,tmpFolder->pidlItem))
+      if (iSearchMethod == SEARCH_PIDL && ILIsEqual((LPITEMIDLIST)searchArg, tmpFolder->pidlItem))
         return i;
       if(iSearchMethod == SEARCH_EXP && tmpFolder->m_iIndent == (int)searchArg)
         return i;
@@ -3554,10 +4003,11 @@ static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMet
  */
 static void FILEDLG95_LOOKIN_Clean(HWND hwnd)
 {
-    FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+    FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
     LookInInfos *liInfos = GetPropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr);
-    int iPos;
-    int iCount = CBGetCount(fodInfos->DlgInfos.hwndLookInCB);
+    int iPos, iCount;
+
+    iCount = SendMessageW(fodInfos->DlgInfos.hwndLookInCB, CB_GETCOUNT, 0, 0);
 
     TRACE("\n");
 
@@ -3567,17 +4017,36 @@ static void FILEDLG95_LOOKIN_Clean(HWND hwnd)
       for(iPos = iCount-1;iPos>=0;iPos--)
       {
         SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(fodInfos->DlgInfos.hwndLookInCB,iPos);
-        COMDLG32_SHFree(tmpFolder->pidlItem);
-        MemFree(tmpFolder);
-        CBDeleteString(fodInfos->DlgInfos.hwndLookInCB,iPos);
+        ILFree(tmpFolder->pidlItem);
+        heap_free(tmpFolder);
+        SendMessageW(fodInfos->DlgInfos.hwndLookInCB, CB_DELETESTRING, iPos, 0);
       }
     }
 
     /* LookInInfos structure */
-    MemFree(liInfos);
+    heap_free(liInfos);
     RemovePropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr);
 }
 
+/***********************************************************************
+ *          get_def_format
+ *
+ * Fill the FORMATETC used in the shell id list
+ */
+static FORMATETC get_def_format(void)
+{
+    static CLIPFORMAT cfFormat;
+    FORMATETC formatetc;
+
+    if (!cfFormat) cfFormat = RegisterClipboardFormatA(CFSTR_SHELLIDLISTA);
+    formatetc.cfFormat = cfFormat;
+    formatetc.ptd = 0;
+    formatetc.dwAspect = DVASPECT_CONTENT;
+    formatetc.lindex = -1;
+    formatetc.tymed = TYMED_HGLOBAL;
+    return formatetc;
+}
+
 /***********************************************************************
  * FILEDLG95_FILENAME_FillFromSelection
  *
@@ -3585,85 +4054,73 @@ static void FILEDLG95_LOOKIN_Clean(HWND hwnd)
  */
 void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd)
 {
-    FileOpenDlgInfos *fodInfos;
+    FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
     LPITEMIDLIST      pidl;
-    UINT              nFiles = 0, nFileToOpen, nFileSelected, nLength = 0;
-    WCHAR             lpstrTemp[MAX_PATH];
-    LPWSTR            lpstrAllFile, lpstrCurrFile;
+    LPWSTR            lpstrAllFiles, lpstrTmp;
+    UINT nFiles = 0, nFileToOpen, nFileSelected, nAllFilesLength = 0, nThisFileLength, nAllFilesMaxLength;
+    STGMEDIUM medium;
+    LPIDA cida;
+    FORMATETC formatetc = get_def_format();
 
     TRACE("\n");
-    fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
-
-    /* Count how many files we have */
-    nFileSelected = GetNumSelected( fodInfos->Shell.FOIDataObject );
-
-    /* calculate the string length, count files */
-    if (nFileSelected >= 1)
-    {
-      nLength += 3;    /* first and last quotes, trailing \0 */
-      for ( nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++ )
-      {
-        pidl = GetPidlFromDataObject( fodInfos->Shell.FOIDataObject, nFileToOpen+1 );
 
-        if (pidl)
-       {
-          /* get the total length of the selected file names */
-          lpstrTemp[0] = '\0';
-          GetName( fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER|SHGDN_FORPARSING, lpstrTemp );
+    if (FAILED(IDataObject_GetData(fodInfos->Shell.FOIDataObject, &formatetc, &medium)))
+        return;
 
-          if ( ! IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl) ) /* Ignore folders */
-         {
-            nLength += lstrlenW( lpstrTemp ) + 3;
-            nFiles++;
-         }
-          COMDLG32_SHFree( pidl );
-       }
-      }
-    }
+    cida = GlobalLock(medium.u.hGlobal);
+    nFileSelected = cida->cidl;
 
-    /* allocate the buffer */
-    if (nFiles <= 1) nLength = MAX_PATH;
-    lpstrAllFile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nLength * sizeof(WCHAR));
+    /* Allocate a buffer */
+    nAllFilesMaxLength = MAX_PATH + 3;
+    lpstrAllFiles = heap_alloc_zero(nAllFilesMaxLength * sizeof(WCHAR));
+    if (!lpstrAllFiles)
+        goto ret;
 
-    /* Generate the string for the edit control */
-    if(nFiles >= 1)
+    /* Loop through the selection, handle only files (not folders) */
+    for (nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++)
     {
-      lpstrCurrFile = lpstrAllFile;
-      for ( nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++ )
-      {
-        pidl = GetPidlFromDataObject( fodInfos->Shell.FOIDataObject, nFileToOpen+1 );
-
+        pidl = (LPITEMIDLIST)((LPBYTE)cida + cida->aoffset[nFileToOpen + 1]);
         if (pidl)
-       {
-         /* get the file name */
-          lpstrTemp[0] = '\0';
-          GetName( fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER|SHGDN_FORPARSING, lpstrTemp );
+        {
+            if (!IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl))
+            {
+                if (nAllFilesLength + MAX_PATH + 3 > nAllFilesMaxLength)
+                {
+                    nAllFilesMaxLength *= 2;
+                    lpstrTmp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpstrAllFiles, nAllFilesMaxLength * sizeof(WCHAR));
+                    if (!lpstrTmp)
+                        goto ret;
+                    lpstrAllFiles = lpstrTmp;
+                }
+                nFiles += 1;
+                lpstrAllFiles[nAllFilesLength++] = '"';
+                GetName(fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING, lpstrAllFiles + nAllFilesLength);
+                nThisFileLength = lstrlenW(lpstrAllFiles + nAllFilesLength);
+                nAllFilesLength += nThisFileLength;
+                lpstrAllFiles[nAllFilesLength++] = '"';
+                lpstrAllFiles[nAllFilesLength++] = ' ';
+            }
+        }
+    }
 
-          if (! IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl)) /* Ignore folders */
-         {
-            if ( nFiles > 1)
-           {
-              *lpstrCurrFile++ =  '\"';
-              lstrcpyW( lpstrCurrFile, lpstrTemp );
-              lpstrCurrFile += lstrlenW( lpstrTemp );
-              *lpstrCurrFile++ = '\"';
-              *lpstrCurrFile++ = ' ';
-              *lpstrCurrFile = 0;
-           }
-           else
-           {
-              lstrcpyW( lpstrAllFile, lpstrTemp );
-           }
-          }
-          COMDLG32_SHFree( pidl );
-       }
-      }
-      SetWindowTextW( fodInfos->DlgInfos.hwndFileName, lpstrAllFile );
-       
-      /* Select the file name like Windows does */ 
-      SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1);
+    if (nFiles != 0)
+    {
+        /* If there's only one file, use the name as-is without quotes */
+        lpstrTmp = lpstrAllFiles;
+        if (nFiles == 1)
+        {
+            lpstrTmp += 1;
+            lpstrTmp[nThisFileLength] = 0;
+        }
+        SetWindowTextW(fodInfos->DlgInfos.hwndFileName, lpstrTmp);
+        /* Select the file name like Windows does */
+        if (filename_is_edit(fodInfos))
+            SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1);
     }
-    HeapFree(GetProcessHeap(),0, lpstrAllFile );
+
+ret:
+    heap_free(lpstrAllFiles);
+    COMCTL32_ReleaseStgMedium(medium);
 }
 
 
@@ -3677,7 +4134,7 @@ static HRESULT COMDLG32_StrRetToStrNW (LPWSTR dest, DWORD len, LPSTRRET src, con
        {
          case STRRET_WSTR:
            lstrcpynW(dest, src->u.pOleStr, len);
-           COMDLG32_SHFree(src->u.pOleStr);
+           CoTaskMemFree(src->u.pOleStr);
            break;
 
          case STRRET_CSTR:
@@ -3705,34 +4162,25 @@ static HRESULT COMDLG32_StrRetToStrNW (LPWSTR dest, DWORD len, LPSTRRET src, con
  */
 static int FILEDLG95_FILENAME_GetFileNames (HWND hwnd, LPWSTR * lpstrFileList, UINT * sizeUsed)
 {
-       FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+       FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
        UINT nFileCount = 0;    /* number of files */
        UINT nStrLen = 0;       /* length of string in edit control */
        LPWSTR lpstrEdit;       /* buffer for string from edit control */
 
        TRACE("\n");
 
-       /* get the filenames from the edit control */
-       nStrLen = SendMessageW(fodInfos->DlgInfos.hwndFileName, WM_GETTEXTLENGTH, 0, 0);
-       lpstrEdit = MemAlloc( (nStrLen+1)*sizeof(WCHAR) );
-       GetDlgItemTextW(hwnd, IDC_FILENAME, lpstrEdit, nStrLen+1);
+       /* get the filenames from the filename control */
+       nStrLen = GetWindowTextLengthW( fodInfos->DlgInfos.hwndFileName );
+       lpstrEdit = heap_alloc( (nStrLen+1)*sizeof(WCHAR) );
+       GetWindowTextW( fodInfos->DlgInfos.hwndFileName, lpstrEdit, nStrLen+1);
 
        TRACE("nStrLen=%u str=%s\n", nStrLen, debugstr_w(lpstrEdit));
 
        nFileCount = COMDLG32_SplitFileNames(lpstrEdit, nStrLen, lpstrFileList, sizeUsed);
-       MemFree(lpstrEdit);
+       heap_free(lpstrEdit);
        return nFileCount;
 }
 
-#define SETDefFormatEtc(fe,cf,med) \
-{ \
-    (fe).cfFormat = cf;\
-    (fe).dwAspect = DVASPECT_CONTENT; \
-    (fe).ptd =NULL;\
-    (fe).tymed = med;\
-    (fe).lindex = -1;\
-};
-
 /*
  * DATAOBJECT Helper functions
  */
@@ -3766,16 +4214,13 @@ LPITEMIDLIST GetPidlFromDataObject ( IDataObject *doSelected, UINT nPidlIndex)
 {
 
     STGMEDIUM medium;
-    FORMATETC formatetc;
+    FORMATETC formatetc = get_def_format();
     LPITEMIDLIST pidl = NULL;
 
     TRACE("sv=%p index=%u\n", doSelected, nPidlIndex);
 
     if (!doSelected)
         return NULL;
-       
-    /* Set the FORMATETC structure*/
-    SETDefFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLISTA), TYMED_HGLOBAL);
 
     /* Get the pidls from IDataObject */
     if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
@@ -3783,7 +4228,7 @@ LPITEMIDLIST GetPidlFromDataObject ( IDataObject *doSelected, UINT nPidlIndex)
       LPIDA cida = GlobalLock(medium.u.hGlobal);
       if(nPidlIndex <= cida->cidl)
       {
-        pidl = COMDLG32_PIDL_ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[nPidlIndex]]));
+        pidl = ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[nPidlIndex]]));
       }
       COMCTL32_ReleaseStgMedium(medium);
     }
@@ -3800,15 +4245,12 @@ static UINT GetNumSelected( IDataObject *doSelected )
 {
     UINT retVal = 0;
     STGMEDIUM medium;
-    FORMATETC formatetc;
+    FORMATETC formatetc = get_def_format();
 
     TRACE("sv=%p\n", doSelected);
 
     if (!doSelected) return 0;
 
-    /* Set the FORMATETC structure*/
-    SETDefFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLISTA), TYMED_HGLOBAL);
-
     /* Get the pidls from IDataObject */
     if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
     {
@@ -3897,8 +4339,8 @@ LPITEMIDLIST GetParentPidl(LPITEMIDLIST pidl)
 
   TRACE("%p\n", pidl);
 
-  pidlParent = COMDLG32_PIDL_ILClone(pidl);
-  COMDLG32_PIDL_ILRemoveLastID(pidlParent);
+  pidlParent = ILClone(pidl);
+  ILRemoveLastID(pidlParent);
 
   return pidlParent;
 }
@@ -3954,8 +4396,8 @@ static BOOL IsPidlFolder (LPSHELLFOLDER psf, LPCITEMIDLIST pidl)
  */
 static BOOL BrowseSelectedFolder(HWND hwnd)
 {
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
   BOOL bBrowseSelFolder = FALSE;
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
 
   TRACE("\n");
 
@@ -3970,212 +4412,30 @@ static BOOL BrowseSelectedFolder(HWND hwnd)
           if ( FAILED( IShellBrowser_BrowseObject( fodInfos->Shell.FOIShellBrowser,
                          pidlSelection, SBSP_RELATIVE ) ) )
           {
-               static const WCHAR notexist[] = {'P','a','t','h',' ','d','o','e','s',
-                                   ' ','n','o','t',' ','e','x','i','s','t',0};
-               MessageBoxW( hwnd, notexist, fodInfos->title, MB_OK | MB_ICONEXCLAMATION );
+               WCHAR buf[64];
+               LoadStringW( COMDLG32_hInstance, IDS_PATHNOTEXISTING, buf, ARRAY_SIZE(buf));
+               MessageBoxW( hwnd, buf, fodInfos->title, MB_OK | MB_ICONEXCLAMATION );
           }
           bBrowseSelFolder = TRUE;
           if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
               SendCustomDlgNotificationMessage(hwnd,CDN_FOLDERCHANGE);
       }
-      COMDLG32_SHFree( pidlSelection );
+      ILFree( pidlSelection );
   }
 
   return bBrowseSelFolder;
 }
 
-/*
- * Memory allocation methods */
-static void *MemAlloc(UINT size)
-{
-    return HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size);
-}
-
-static void MemFree(void *mem)
-{
-    HeapFree(GetProcessHeap(),0,mem);
-}
-
-/*
- * Old-style (win3.1) dialogs */
-
-/***********************************************************************
- *           FD32_GetTemplate                                  [internal]
- *
- * Get a template (or FALSE if failure) when 16 bits dialogs are used
- * by a 32 bits application
- *
- */
-BOOL FD32_GetTemplate(PFD31_DATA lfs)
-{
-    LPOPENFILENAMEW ofnW = lfs->ofnW;
-    LPOPENFILENAMEA ofnA = lfs->ofnA;
-    HANDLE hDlgTmpl;
-
-    if (ofnW->Flags & OFN_ENABLETEMPLATEHANDLE)
-    {
-       if (!(lfs->template = LockResource( ofnW->hInstance )))
-       {
-           COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
-           return FALSE;
-       }
-    }
-    else if (ofnW->Flags & OFN_ENABLETEMPLATE)
-    {
-       HRSRC hResInfo;
-        if (ofnA)
-           hResInfo = FindResourceA(ofnA->hInstance,
-                                ofnA->lpTemplateName,
-                                 (LPSTR)RT_DIALOG);
-        else
-           hResInfo = FindResourceW(ofnW->hInstance,
-                                ofnW->lpTemplateName,
-                                 (LPWSTR)RT_DIALOG);
-        if (!hResInfo)
-       {
-           COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
-           return FALSE;
-       }
-       if (!(hDlgTmpl = LoadResource(ofnW->hInstance,
-                               hResInfo)) ||
-                   !(lfs->template = LockResource(hDlgTmpl)))
-       {
-           COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
-           return FALSE;
-       }
-    } else { /* get it from internal Wine resource */
-       HRSRC hResInfo;
-       if (!(hResInfo = FindResourceA(COMDLG32_hInstance,
-             lfs->open? "OPEN_FILE":"SAVE_FILE", (LPSTR)RT_DIALOG)))
-       {
-           COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
-           return FALSE;
-        }
-        if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo )) ||
-                !(lfs->template = LockResource( hDlgTmpl )))
-        {
-            COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
-            return FALSE;
-        }
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *                              FD32_WMMeasureItem           [internal]
- */
-static LONG FD32_WMMeasureItem(LPARAM lParam)
-{
-    LPMEASUREITEMSTRUCT lpmeasure;
-
-    lpmeasure = (LPMEASUREITEMSTRUCT)lParam;
-    lpmeasure->itemHeight = FD31_GetFldrHeight();
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           FileOpenDlgProc                                    [internal]
- *      Used for open and save, in fact.
- */
-static INT_PTR CALLBACK FD32_FileOpenDlgProc(HWND hWnd, UINT wMsg,
-                                             WPARAM wParam, LPARAM lParam)
-{
-    PFD31_DATA lfs = (PFD31_DATA)GetPropA(hWnd,FD31_OFN_PROP);
-
-    TRACE("msg=%x wparam=%lx lParam=%lx\n", wMsg, wParam, lParam);
-    if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
-        {
-            INT_PTR lRet;
-            lRet  = (INT_PTR)FD31_CallWindowProc(lfs, wMsg, wParam, lParam);
-            if (lRet)
-                return lRet;         /* else continue message processing */
-        }
-    switch (wMsg)
-    {
-    case WM_INITDIALOG:
-        return FD31_WMInitDialog(hWnd, wParam, lParam);
-
-    case WM_MEASUREITEM:
-        return FD32_WMMeasureItem(lParam);
-
-    case WM_DRAWITEM:
-        return FD31_WMDrawItem(hWnd, wParam, lParam, !lfs->open, (DRAWITEMSTRUCT *)lParam);
-
-    case WM_COMMAND:
-        return FD31_WMCommand(hWnd, lParam, HIWORD(wParam), LOWORD(wParam), lfs);
-#if 0
-    case WM_CTLCOLOR:
-         SetBkColor((HDC16)wParam, 0x00C0C0C0);
-         switch (HIWORD(lParam))
-         {
-        case CTLCOLOR_BTN:
-            SetTextColor((HDC16)wParam, 0x00000000);
-             return hGRAYBrush;
-       case CTLCOLOR_STATIC:
-             SetTextColor((HDC16)wParam, 0x00000000);
-             return hGRAYBrush;
-       }
-      break;
-#endif
-    }
-    return FALSE;
-}
-
-
-/***********************************************************************
- *           GetFileName31A                                 [internal]
- *
- * Creates a win31 style dialog box for the user to select a file to open/save.
- */
-static BOOL GetFileName31A(LPOPENFILENAMEA lpofn, /* address of structure with data*/
-                           UINT dlgType /* type dialogue : open/save */
-                           )
+static inline BOOL valid_struct_size( DWORD size )
 {
-    BOOL bRet = FALSE;
-    PFD31_DATA lfs;
-
-    if (!lpofn || !FD31_Init()) return FALSE;
-
-    TRACE("ofn flags %08x\n", lpofn->Flags);
-    lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, FALSE);
-    if (lfs)
-    {
-        bRet = DialogBoxIndirectParamA( COMDLG32_hInstance, lfs->template, lpofn->hwndOwner,
-                                        FD32_FileOpenDlgProc, (LPARAM)lfs);
-        FD31_DestroyPrivate(lfs);
-    }
-
-    TRACE("return lpstrFile='%s' !\n", lpofn->lpstrFile);
-    return bRet;
+    return (size == OPENFILENAME_SIZE_VERSION_400W) ||
+        (size == sizeof( OPENFILENAMEW ));
 }
 
-/***********************************************************************
- *           GetFileName31W                                 [internal]
- *
- * Creates a win31 style dialog box for the user to select a file to open/save
- */
-static BOOL GetFileName31W(LPOPENFILENAMEW lpofn, /* address of structure with data*/
-                           UINT dlgType /* type dialogue : open/save */
-                           )
+static inline BOOL is_win16_looks(DWORD flags)
 {
-    BOOL bRet = FALSE;
-    PFD31_DATA lfs;
-
-    if (!lpofn || !FD31_Init()) return FALSE;
-
-    lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, TRUE);
-    if (lfs)
-    {
-        bRet = DialogBoxIndirectParamW( COMDLG32_hInstance, lfs->template, lpofn->hwndOwner,
-                                        FD32_FileOpenDlgProc, (LPARAM)lfs);
-        FD31_DestroyPrivate(lfs);
-    }
-
-    TRACE("file %s, file offset %d, ext offset %d\n",
-          debugstr_w(lpofn->lpstrFile), lpofn->nFileOffset, lpofn->nFileExtension);
-    return bRet;
+    return (flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE) &&
+            !(flags & OFN_EXPLORER));
 }
 
 /* ------------------ APIs ---------------------- */
@@ -4190,24 +4450,29 @@ static BOOL GetFileName31W(LPOPENFILENAMEW lpofn, /* address of structure with d
  *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
  *
  */
-BOOL WINAPI GetOpenFileNameA(
-       LPOPENFILENAMEA ofn) /* [in/out] address of init structure */
+BOOL WINAPI GetOpenFileNameA(OPENFILENAMEA *ofn)
 {
-    BOOL win16look = FALSE;
+    TRACE("flags 0x%08x\n", ofn->Flags);
 
-    TRACE("flags %08x\n", ofn->Flags);
+    if (!valid_struct_size( ofn->lStructSize ))
+    {
+        COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE );
+        return FALSE;
+    }
 
     /* OFN_FILEMUSTEXIST implies OFN_PATHMUSTEXIST */
     if (ofn->Flags & OFN_FILEMUSTEXIST)
         ofn->Flags |= OFN_PATHMUSTEXIST;
 
-    if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
-        win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE;
-
-    if (win16look)
+    if (is_win16_looks(ofn->Flags))
         return GetFileName31A(ofn, OPEN_DIALOG);
     else
-        return GetFileDialog95A(ofn, OPEN_DIALOG);
+    {
+        FileOpenDlgInfos info;
+
+        init_filedlg_infoA(ofn, &info);
+        return GetFileDialog95(&info, OPEN_DIALOG);
+    }
 }
 
 /***********************************************************************
@@ -4220,24 +4485,29 @@ BOOL WINAPI GetOpenFileNameA(
  *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
  *
  */
-BOOL WINAPI GetOpenFileNameW(
-       LPOPENFILENAMEW ofn) /* [in/out] address of init structure */
+BOOL WINAPI GetOpenFileNameW(OPENFILENAMEW *ofn)
 {
-    BOOL win16look = FALSE;
+    TRACE("flags 0x%08x\n", ofn->Flags);
 
-    TRACE("flags %08x\n", ofn->Flags);
+    if (!valid_struct_size( ofn->lStructSize ))
+    {
+        COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE );
+        return FALSE;
+    }
 
     /* OFN_FILEMUSTEXIST implies OFN_PATHMUSTEXIST */
     if (ofn->Flags & OFN_FILEMUSTEXIST)
         ofn->Flags |= OFN_PATHMUSTEXIST;
 
-    if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
-        win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE;
-
-    if (win16look)
+    if (is_win16_looks(ofn->Flags))
         return GetFileName31W(ofn, OPEN_DIALOG);
     else
-        return GetFileDialog95W(ofn, OPEN_DIALOG);
+    {
+        FileOpenDlgInfos info;
+
+        init_filedlg_infoW(ofn, &info);
+        return GetFileDialog95(&info, OPEN_DIALOG);
+    }
 }
 
 
@@ -4251,18 +4521,23 @@ BOOL WINAPI GetOpenFileNameW(
  *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
  *
  */
-BOOL WINAPI GetSaveFileNameA(
-       LPOPENFILENAMEA ofn) /* [in/out] address of init structure */
+BOOL WINAPI GetSaveFileNameA(OPENFILENAMEA *ofn)
 {
-    BOOL win16look = FALSE;
-
-    if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
-        win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE;
+    if (!valid_struct_size( ofn->lStructSize ))
+    {
+        COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE );
+        return FALSE;
+    }
 
-    if (win16look)
+    if (is_win16_looks(ofn->Flags))
         return GetFileName31A(ofn, SAVE_DIALOG);
     else
-        return GetFileDialog95A(ofn, SAVE_DIALOG);
+    {
+        FileOpenDlgInfos info;
+
+        init_filedlg_infoA(ofn, &info);
+        return GetFileDialog95(&info, SAVE_DIALOG);
+    }
 }
 
 /***********************************************************************
@@ -4278,15 +4553,21 @@ BOOL WINAPI GetSaveFileNameA(
 BOOL WINAPI GetSaveFileNameW(
        LPOPENFILENAMEW ofn) /* [in/out] address of init structure */
 {
-    BOOL win16look = FALSE;
-
-    if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
-        win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE;
+    if (!valid_struct_size( ofn->lStructSize ))
+    {
+        COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE );
+        return FALSE;
+    }
 
-    if (win16look)
+    if (is_win16_looks(ofn->Flags))
         return GetFileName31W(ofn, SAVE_DIALOG);
     else
-        return GetFileDialog95W(ofn, SAVE_DIALOG);
+    {
+        FileOpenDlgInfos info;
+
+        init_filedlg_infoW(ofn, &info);
+        return GetFileDialog95(&info, SAVE_DIALOG);
+    }
 }
 
 /***********************************************************************
@@ -4301,11 +4582,11 @@ short WINAPI GetFileTitleA(LPCSTR lpFile, LPSTR lpTitle, WORD cbBuf)
     LPWSTR lpWTitle;
 
     RtlCreateUnicodeStringFromAsciiz(&strWFile, lpFile);
-    lpWTitle = RtlAllocateHeap( GetProcessHeap(), 0, cbBuf*sizeof(WCHAR));
+    lpWTitle = heap_alloc(cbBuf * sizeof(WCHAR));
     ret = GetFileTitleW(strWFile.Buffer, lpWTitle, cbBuf);
     if (!ret) WideCharToMultiByte( CP_ACP, 0, lpWTitle, -1, lpTitle, cbBuf, NULL, NULL );
     RtlFreeUnicodeString( &strWFile );
-    RtlFreeHeap( GetProcessHeap(), 0, lpWTitle );
+    heap_free( lpWTitle );
     return ret;
 }