[COMDLG32] Save open/save location by extension (#1514)
[reactos.git] / dll / win32 / comdlg32 / filedlg.c
index 3fa4255..eed9f59 100644 (file)
  *
  */
 
+#include "config.h"
+#include "wine/port.h"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+
+#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 "cderr.h"
+#include "shellapi.h"
+#include "shlobj.h"
+#include "filedlgbrowser.h"
+#include "shlwapi.h"
+
+#include "wine/unicode.h"
+#include "wine/debug.h"
+#include "wine/heap.h"
 
-#include <shellapi.h>
+WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
 
 #define UNIMPLEMENTED_FLAGS \
 (OFN_DONTADDTORECENT |\
 OFN_NODEREFERENCELINKS | OFN_NOREADONLYRETURN |\
 OFN_NOTESTFILECREATE /*| OFN_USEMONIKERS*/)
 
-#define IsHooked(fodInfos) \
-       ((fodInfos->ofnInfos->Flags & OFN_ENABLEHOOK) && fodInfos->ofnInfos->lpfnHook)
 /***********************************************************************
  * Data structure and global variables
  */
@@ -93,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 */
 
@@ -144,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
  */
@@ -162,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);
@@ -188,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);
@@ -196,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
  *
@@ -218,14 +362,11 @@ static BOOL BrowseSelectedFolder(HWND hwnd);
  */
 static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
 {
-
     LRESULT lRes;
-    LPCVOID origTemplate;
-    DWORD dwSize;
-    LPDLGTEMPLATEW template;
+    void *template;
     HRSRC hRes;
     HANDLE hDlgTmpl = 0;
-    HRESULT hr;
+    WORD templateid;
 
     /* test for missing functionality */
     if (fodInfos->ofnInfos->Flags & UNIMPLEMENTED_FLAGS)
@@ -236,44 +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 (!(dwSize = SizeofResource(COMDLG32_hInstance, hRes)) ||
-        !(hDlgTmpl = LoadResource(COMDLG32_hInstance, hRes)) ||
-        !(origTemplate = LockResource(hDlgTmpl)))
+    if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hRes )) ||
+        !(template = LockResource( hDlgTmpl )))
     {
         COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
         return FALSE;
     }
-    if (!(template = HeapAlloc(GetProcessHeap(), 0, dwSize)))
-    {
-        COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE);
-        return FALSE;
-    }
-    memcpy(template, origTemplate, 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)
     {
-        template->style |= WS_SIZEBOX;
         fodInfos->sizedlg.cx = fodInfos->sizedlg.cy = 0;
         fodInfos->initial_size.x = fodInfos->initial_size.y = 0;
     }
-    else
-        template->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);
@@ -281,9 +416,6 @@ 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,
                                      template,
@@ -296,11 +428,9 @@ static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
                                      fodInfos->ofnInfos->hwndOwner,
                                      FileOpenDlgProc95,
                                      (LPARAM) fodInfos);
-    if (SUCCEEDED(hr)) 
+    if (fodInfos->ole_initialized)
         OleUninitialize();
 
-    HeapFree(GetProcessHeap(), 0, template);
-
     /* Unable to create the dialog */
     if( lRes == -1)
         return FALSE;
@@ -308,234 +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;
-  INITCOMMONCONTROLSEX icc;
-
-  /* Initialize ComboBoxEx32 */
-  icc.dwSize = sizeof(icc);
-  icc.dwICC = ICC_USEREX_CLASSES;
-  InitCommonControlsEx(&icc);
-
-  /* Initialize CommDlgExtendedError() */
-  COMDLG32_SetCommDlgExtendedError(0);
-
-  /* Initialize FileOpenDlgInfos structure */
-  ZeroMemory(&fodInfos, sizeof(FileOpenDlgInfos));
-
-  /* Pass in the original ofn */
-  fodInfos.ofnInfos = (LPOPENFILENAMEW)ofn;
-
-  /* save current directory */
-  if (ofn->Flags & OFN_NOCHANGEDIR)
-  {
-     lpstrSavDir = MemAlloc(MAX_PATH);
-     GetCurrentDirectoryA(MAX_PATH, lpstrSavDir);
-  }
+    WCHAR *ret;
+    INT len;
 
-  fodInfos.unicode = FALSE;
+    if (!str)
+        return NULL;
 
-  /* 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;
+    len = MultiByteToWideChar(CP_ACP, 0, str, -1, 0, 0);
+    ret = heap_alloc(len * sizeof(WCHAR));
+    MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
 
-  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;
+    return ret;
+}
 
-  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;
+static void init_filedlg_infoW(OPENFILENAMEW *ofn, FileOpenDlgInfos *info)
+{
+    INITCOMMONCONTROLSEX icc;
 
-  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;
+    /* Initialize ComboBoxEx32 */
+    icc.dwSize = sizeof(icc);
+    icc.dwICC = ICC_USEREX_CLASSES;
+    InitCommonControlsEx(&icc);
 
-  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;
+    /* Initialize CommDlgExtendedError() */
+    COMDLG32_SetCommDlgExtendedError(0);
 
-  /* 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;
+    memset(info, 0, sizeof(*info));
 
-  /* Initialize the dialog property */
-  fodInfos.DlgInfos.dwDlgProp = 0;
-  fodInfos.DlgInfos.hwndCustomDlg = NULL;
+    /* Pass in the original ofn */
+    info->ofnInfos = ofn;
 
-  switch(iDlgType)
-  {
-    case OPEN_DIALOG :
-      ret = GetFileName95(&fodInfos);
-      break;
-    case SAVE_DIALOG :
-      fodInfos.DlgInfos.dwDlgProp |= FODPROP_SAVEDLG;
-      ret = GetFileName95(&fodInfos);
-      break;
-    default :
-      ret = FALSE;
-  }
+    info->title = ofn->lpstrTitle;
+    info->defext = ofn->lpstrDefExt;
+    info->filter = ofn->lpstrFilter;
+    info->customfilter = ofn->lpstrCustomFilter;
 
-  if (lpstrSavDir)
-  {
-      SetCurrentDirectoryA(lpstrSavDir);
-      MemFree(lpstrSavDir);
-  }
+    if (ofn->lpstrFile)
+    {
+        info->filename = heap_alloc(ofn->nMaxFile * sizeof(WCHAR));
+        lstrcpynW(info->filename, ofn->lpstrFile, ofn->nMaxFile);
+    }
 
-  MemFree(title);
-  MemFree(defext);
-  MemFree(filter);
-  MemFree(customfilter);
-  MemFree(fodInfos.initdir);
-  MemFree(fodInfos.filename);
+    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);
+        }
+    }
 
-  TRACE("selected file: %s\n",ofn->lpstrFile);
+    info->unicode = TRUE;
+}
 
-  return ret;
+static void init_filedlg_infoA(OPENFILENAMEA *ofn, FileOpenDlgInfos *info)
+{
+    OPENFILENAMEW ofnW;
+    int len;
+
+    ofnW = *(OPENFILENAMEW *)ofn;
+
+    ofnW.lpstrInitialDir = heap_strdupAtoW(ofn->lpstrInitialDir);
+    ofnW.lpstrDefExt = heap_strdupAtoW(ofn->lpstrDefExt);
+    ofnW.lpstrTitle = heap_strdupAtoW(ofn->lpstrTitle);
+
+    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;
+    }
+
+    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;
-  INITCOMMONCONTROLSEX icc;
+    WCHAR *current_dir = NULL;
+    unsigned int i;
+    BOOL ret;
 
-  /* Initialize ComboBoxEx32 */
-  icc.dwSize = sizeof(icc);
-  icc.dwICC = ICC_USEREX_CLASSES;
-  InitCommonControlsEx(&icc);
-
-  /* Initialize CommDlgExtendedError() */
-  COMDLG32_SetCommDlgExtendedError(0);
-
-  /* Initialize FileOpenDlgInfos structure */
-  ZeroMemory(&fodInfos, sizeof(FileOpenDlgInfos));
-
-  /*  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 = FALSE;
-  }
+    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;
 }
 
 /******************************************************************************
@@ -577,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))
@@ -612,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 */
@@ -621,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++;
@@ -813,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
@@ -859,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  {
@@ -900,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;
 }
 
@@ -940,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");
 
@@ -949,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)
     {
@@ -969,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;
 }
 
@@ -980,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;
 
@@ -1007,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;
@@ -1063,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)
     {
@@ -1091,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) ||
@@ -1188,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;
             }
         }
     }
@@ -1248,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 |
@@ -1336,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;
@@ -1426,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);
 
@@ -1475,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);
@@ -1496,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)
   {
@@ -1515,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);
   }
 
@@ -1535,12 +1698,18 @@ 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",
@@ -1556,42 +1725,58 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
   /* 2. (All platforms) If initdir is not null, then use it */
   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) {
-          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 && (!fodInfos->initdir || !*fodInfos->initdir))
   {
@@ -1613,8 +1798,8 @@ 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;
@@ -1626,7 +1811,7 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
 
       /* 4. Win2000+: Recently used */
       if (!handledPath && win2000plus) {
-          fodInfos->initdir = MemAlloc(MAX_PATH * sizeof(WCHAR));
+          fodInfos->initdir = heap_alloc(MAX_PATH * sizeof(WCHAR));
           fodInfos->initdir[0] = '\0';
 
           FILEDLG95_MRU_load_filename(fodInfos->initdir);
@@ -1634,7 +1819,7 @@ 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;
           }
       }
@@ -1666,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;
@@ -1681,24 +1866,25 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
 
       /* 6. Win98+ and 2000+: Use personal files dir, others use current dir */
       if (!handledPath && (win2000plus || win98plus)) {
-          fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR));
+          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) {
-          fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR));
+          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));
@@ -1714,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);
@@ -1731,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);
   }
 
@@ -1758,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))
@@ -1776,10 +1962,10 @@ static LRESULT FILEDLG95_ResizeControls(HWND hwnd, WPARAM wParam, LPARAM lParam)
   }
   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))))
     {
@@ -1831,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;
 }
@@ -1847,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
  *
@@ -1854,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:
@@ -1895,9 +2094,24 @@ 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 edt1:
@@ -1917,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");
 
@@ -1939,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;
 
@@ -1975,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");
 
@@ -2027,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);
     }
   }
 
@@ -2165,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;
     }
@@ -2190,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);
@@ -2201,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 */
@@ -2252,7 +2467,8 @@ 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, sizeof(module_path)/sizeof(module_path[0]))) {
+    if (!GetModuleFileNameW(GetModuleHandleW(NULL), module_path, ARRAY_SIZE(module_path)))
+    {
         WARN("GotModuleFileName failed: %d\n", GetLastError());
         return;
     }
@@ -2265,16 +2481,256 @@ static void FILEDLG95_MRU_load_filename(LPWSTR stored_path)
     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)
+{
+    HKEY hOpenSaveMRT = NULL;
+    LONG result;
+    MRUINFOW mi;
+    HANDLE hList;
+    LPCWSTR defext = PathFindExtensionW(filename);
+
+    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)
+        {
+            (*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);
 }
 
@@ -2358,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))
@@ -2390,7 +2846,7 @@ int FILEDLG95_ValidatePathAction(LPWSTR lpstrPathAndFile, IShellFolder **ppsf,
             break;
         }
     }
-    if(pidl) COMDLG32_SHFree(pidl);
+    ILFree(pidl);
 
     return nOpenAction;
 }
@@ -2404,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;
@@ -2411,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);
 
@@ -2443,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
@@ -2490,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 */
@@ -2509,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 )
@@ -2522,9 +2979,16 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
             if (fodInfos->Shell.FOIShellView)
               IShellView_Refresh(fodInfos->Shell.FOIShellView);
          }
-          COMDLG32_SHFree(pidlCurrent);
+          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;
@@ -2559,7 +3023,7 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
             if (lpstrFilter != (LPWSTR)CB_ERR)  /* control is not empty */
             {
                 WCHAR* filterSearchIndex;
-                filterExt = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(lpstrFilter) + 1) * sizeof(WCHAR));
+                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
@@ -2571,16 +3035,17 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
                     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 = PathFindExtensionW(filterExt);
-                if (*filterSearchIndex++ && !strchrW(filterSearchIndex, '*') && !strchrW(filterSearchIndex, '?'))
+                filterSearchIndex = strchrW(filterExt, '.');
+                if (filterSearchIndex++ && !strchrW(filterSearchIndex, '*') && !strchrW(filterSearchIndex, '?'))
                 {
                     strcpyW(filterExt, filterSearchIndex);
                 }
                 else
                 {
-                    HeapFree(GetProcessHeap(), 0, filterExt);
+                    heap_free(filterExt);
                     filterExt = NULL;
                 }
             }
@@ -2588,7 +3053,7 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
             if (!filterExt)
             {
                 /* use the default file extension */
-                filterExt = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(fodInfos->defext) + 1) * sizeof(WCHAR));
+                filterExt = heap_alloc((lstrlenW(fodInfos->defext) + 1) * sizeof(WCHAR));
                 strcpyW(filterExt, fodInfos->defext);
             }
 
@@ -2600,7 +3065,7 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
                 lstrcatW(lpstrPathAndFile, filterExt);
             }
 
-            HeapFree(GetProcessHeap(), 0, filterExt);
+            heap_free(filterExt);
 
             /* In Open dialog: if file does not exist try without extension */
             if (!(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG) && !PathFileExistsW(lpstrPathAndFile))
@@ -2709,23 +3174,6 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
               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)
           {
@@ -2746,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);
@@ -2781,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
@@ -2816,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);
@@ -2847,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");
 
@@ -2861,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
  *
@@ -2890,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)
@@ -2902,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);
@@ -2915,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)
   {
@@ -2934,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)
@@ -2960,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;
@@ -3000,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,
@@ -3014,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
@@ -3030,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)
   {
@@ -3039,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);
@@ -3055,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);
@@ -3075,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));
 
@@ -3097,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");
 
@@ -3108,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);
 }
 
 /***********************************************************************
@@ -3150,9 +3584,9 @@ static void FILEDLG95_LOOKIN_Init(HWND hwndCombo)
   LPITEMIDLIST pidlDrives, pidlTmp, pidlTmp1, pidlAbsTmp;
   HDC hdc;
   TEXTMETRICW tm;
-  LookInInfos *liInfos = MemAlloc(sizeof(LookInInfos));
+  LookInInfos *liInfos = heap_alloc_zero(sizeof(*liInfos));
 
-  TRACE("\n");
+  TRACE("%p\n", hwndCombo);
 
   liInfos->iMaxIndentation = 0;
 
@@ -3164,16 +3598,16 @@ static void FILEDLG95_LOOKIN_Init(HWND hwndCombo)
   ReleaseDC( hwndCombo, hdc );
 
   /* set item height for both text field and listbox */
-  CBSetItemHeight( hwndCombo, -1, max( tm.tmHeight, GetSystemMetrics(SM_CYSMICON) ));
-  CBSetItemHeight( hwndCombo, 0, max( tm.tmHeight, 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);
 
@@ -3192,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)))
            {
@@ -3201,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);
              }
@@ -3213,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);
 }
 
 /***********************************************************************
@@ -3240,7 +3674,6 @@ 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;
 
@@ -3263,16 +3696,8 @@ static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct)
       shgfi_flags |= SHGFI_SMALLICON;
   }
 
-  if(pDIStruct->itemID == liInfos->uSelectedItem)
-  {
-    ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
-                                               0, &sfi, sizeof (sfi), shgfi_flags );
-  }
-  else
-  {
-    ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
-                                               0, &sfi, sizeof (sfi), shgfi_flags );
-  }
+  ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
+                                             0, &sfi, sizeof (sfi), shgfi_flags );
 
   /* Is this item selected ? */
   if(pDIStruct->itemState & ODS_SELECTED)
@@ -3290,16 +3715,10 @@ 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_flags );
-
-  }
   else
-  {
     iIndentation = tmpFolder->m_iIndent;
-  }
+
   /* Draw text and icon */
 
   /* Initialise the icon display area */
@@ -3338,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);
 
@@ -3349,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;
 
@@ -3386,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;
@@ -3394,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;
@@ -3414,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))
   {
@@ -3428,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;
 
 }
@@ -3469,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);
 }
@@ -3486,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);
 
@@ -3512,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;
@@ -3537,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;
@@ -3557,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);
 
@@ -3567,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;
@@ -3584,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");
 
@@ -3597,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
  *
@@ -3615,86 +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 );
+    if (FAILED(IDataObject_GetData(fodInfos->Shell.FOIDataObject, &formatetc, &medium)))
+        return;
 
-    /* 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 );
+    cida = GlobalLock(medium.u.hGlobal);
+    nFileSelected = cida->cidl;
 
-        if (pidl)
-       {
-          /* get the total length of the selected file names */
-          lpstrTemp[0] = '\0';
-          GetName( fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER|SHGDN_FORPARSING, lpstrTemp );
+    /* Allocate a buffer */
+    nAllFilesMaxLength = MAX_PATH + 3;
+    lpstrAllFiles = heap_alloc_zero(nAllFilesMaxLength * sizeof(WCHAR));
+    if (!lpstrAllFiles)
+        goto ret;
 
-          if ( ! IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl) ) /* Ignore folders */
-         {
-            nLength += lstrlenW( lpstrTemp ) + 3;
-            nFiles++;
-         }
-          COMDLG32_SHFree( pidl );
-       }
-      }
-    }
-
-    /* allocate the buffer */
-    if (nFiles <= 1) nLength = MAX_PATH;
-    lpstrAllFile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nLength * sizeof(WCHAR));
-
-    /* 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 */
-      if (filename_is_edit( fodInfos ))
-          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);
 }
 
 
@@ -3708,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:
@@ -3736,7 +4162,7 @@ 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 */
@@ -3745,25 +4171,16 @@ static int FILEDLG95_FILENAME_GetFileNames (HWND hwnd, LPWSTR * lpstrFileList, U
 
        /* get the filenames from the filename control */
        nStrLen = GetWindowTextLengthW( fodInfos->DlgInfos.hwndFileName );
-       lpstrEdit = MemAlloc( (nStrLen+1)*sizeof(WCHAR) );
+       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
  */
@@ -3797,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)))
@@ -3814,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);
     }
@@ -3831,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)))
     {
@@ -3928,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;
 }
@@ -3985,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");
 
@@ -4001,32 +4412,20 @@ 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);
-}
-
 static inline BOOL valid_struct_size( DWORD size )
 {
     return (size == OPENFILENAME_SIZE_VERSION_400W) ||
@@ -4051,10 +4450,9 @@ static inline BOOL is_win16_looks(DWORD flags)
  *    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)
 {
-    TRACE("flags %08x\n", ofn->Flags);
+    TRACE("flags 0x%08x\n", ofn->Flags);
 
     if (!valid_struct_size( ofn->lStructSize ))
     {
@@ -4069,7 +4467,12 @@ BOOL WINAPI GetOpenFileNameA(
     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);
+    }
 }
 
 /***********************************************************************
@@ -4082,10 +4485,9 @@ 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)
 {
-    TRACE("flags %08x\n", ofn->Flags);
+    TRACE("flags 0x%08x\n", ofn->Flags);
 
     if (!valid_struct_size( ofn->lStructSize ))
     {
@@ -4100,7 +4502,12 @@ BOOL WINAPI GetOpenFileNameW(
     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);
+    }
 }
 
 
@@ -4114,8 +4521,7 @@ 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)
 {
     if (!valid_struct_size( ofn->lStructSize ))
     {
@@ -4126,7 +4532,12 @@ BOOL WINAPI GetSaveFileNameA(
     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);
+    }
 }
 
 /***********************************************************************
@@ -4151,7 +4562,12 @@ BOOL WINAPI GetSaveFileNameW(
     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);
+    }
 }
 
 /***********************************************************************
@@ -4166,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;
 }