[COMDLG32] Sync with Wine Staging 3.3. CORE-14434
[reactos.git] / dll / win32 / comdlg32 / filedlg.c
index cb2b076..41b7966 100644 (file)
  *
  */
 
-// RegGetValueW is supported by Win2k3 SP1 but headers need Win Vista
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600
-
-#define WIN32_NO_STATUS
-#define _INC_WINDOWS
-#define COM_NO_WINDOWS_H
+#include "config.h"
+#include "wine/port.h"
 
-#include <config.h>
-//#include "wine/port.h"
-
-//#include <ctype.h>
-//#include <stdlib.h>
+#include <ctype.h>
+#include <stdlib.h>
 #include <stdarg.h>
-//#include <stdio.h>
-//#include <string.h>
+#include <stdio.h>
+#include <string.h>
 
 #define COBJMACROS
 #define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include <windef.h>
-//#include "winbase.h"
-#include <winternl.h>
-//#include "winnls.h"
-#include <wingdi.h>
-#include <winreg.h>
-#include <winuser.h>
-#include <commdlg.h>
-//#include "dlgs.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "winnls.h"
+#include "wingdi.h"
+#ifdef __REACTOS__
+/* RegGetValueW is supported by Win2k3 SP1 but headers need Win Vista */
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#endif
+#include "winreg.h"
+#include "winuser.h"
+#include "commdlg.h"
+#include "dlgs.h"
 #include "cdlg.h"
-#include "filedlg31.h"
-#include <cderr.h>
-//#include "shellapi.h"
-//#include "shlobj.h"
+#include "cderr.h"
+#include "shellapi.h"
+#include "shlobj.h"
 #include "filedlgbrowser.h"
-#include <shlwapi.h>
+#include "shlwapi.h"
 
-#include <wine/unicode.h>
-#include <wine/debug.h>
+#include "wine/unicode.h"
+#include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
 
@@ -119,7 +114,6 @@ typedef struct tagLookInInfo
  */
 
 /* Draw item constant */
-#define ICONWIDTH 18
 #define XTEXTOFFSET 3
 
 /* AddItem flags*/
@@ -173,7 +167,6 @@ typedef struct tagLookInInfo
 #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 */
 
@@ -184,6 +177,13 @@ 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);
+}
+
 /***********************************************************************
  * Prototypes
  */
@@ -236,6 +236,7 @@ LPITEMIDLIST  GetParentPidl(LPITEMIDLIST pidl);
 static LPITEMIDLIST GetPidlFromName(IShellFolder *psf,LPWSTR lpcstrFileName);
 static BOOL IsPidlFolder (LPSHELLFOLDER psf, LPCITEMIDLIST pidl);
 static UINT GetNumSelected( IDataObject *doSelected );
+static void COMCTL32_ReleaseStgMedium(STGMEDIUM medium);
 
 /* Shell memory allocation */
 static void *MemAlloc(UINT size);
@@ -258,14 +259,10 @@ static BOOL BrowseSelectedFolder(HWND hwnd);
  */
 static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
 {
-
     LRESULT lRes;
-    LPVOID template;
+    void *template;
     HRSRC hRes;
     HANDLE hDlgTmpl = 0;
-    HRESULT hr;
-    DWORD dwSize;
-    LPDLGTEMPLATE hDialogTemplate;
 
     /* test for missing functionality */
     if (fodInfos->ofnInfos->Flags & UNIMPLEMENTED_FLAGS)
@@ -282,33 +279,24 @@ static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
         return FALSE;
     }
     if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hRes )) ||
-        !(dwSize = SizeofResource(COMDLG32_hInstance, hRes )) ||
-        !(hDialogTemplate = malloc(dwSize)) ||
         !(template = LockResource( hDlgTmpl )))
     {
         COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
         return FALSE;
     }
 
-    /* Copy the read only resource */
-    memcpy(hDialogTemplate, template, dwSize);
-
     /* msdn: explorer style dialogs permit sizing by default.
      * The OFN_ENABLESIZING flag is only needed when a hook or
-     * custom tmeplate is provided */
+     * custom template is provided */
     if( (fodInfos->ofnInfos->Flags & OFN_EXPLORER) &&
             !(fodInfos->ofnInfos->Flags & ( OFN_ENABLEHOOK | OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE)))
         fodInfos->ofnInfos->Flags |= OFN_ENABLESIZING;
 
     if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
     {
-        hDialogTemplate->style |= WS_SIZEBOX;
         fodInfos->sizedlg.cx = fodInfos->sizedlg.cy = 0;
         fodInfos->initial_size.x = fodInfos->initial_size.y = 0;
     }
-    else
-        hDialogTemplate->style &= ~WS_SIZEBOX;
-
 
     /* old style hook messages */
     if (IsHooked(fodInfos))
@@ -319,26 +307,21 @@ static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
       fodInfos->HookMsg.sharevistring = RegisterWindowMessageW(SHAREVISTRINGW);
     }
 
-    /* Some shell namespace extensions depend on COM being initialized. */
-    hr = OleInitialize(NULL);
-
     if (fodInfos->unicode)
       lRes = DialogBoxIndirectParamW(COMDLG32_hInstance,
-                                     hDialogTemplate,
+                                     template,
                                      fodInfos->ofnInfos->hwndOwner,
                                      FileOpenDlgProc95,
                                      (LPARAM) fodInfos);
     else
       lRes = DialogBoxIndirectParamA(COMDLG32_hInstance,
-                                     hDialogTemplate,
+                                     template,
                                      fodInfos->ofnInfos->hwndOwner,
                                      FileOpenDlgProc95,
                                      (LPARAM) fodInfos);
-    if (SUCCEEDED(hr))
+    if (fodInfos->ole_initialized)
         OleUninitialize();
 
-    free(hDialogTemplate);
-
     /* Unable to create the dialog */
     if( lRes == -1)
         return FALSE;
@@ -346,222 +329,187 @@ static BOOL GetFileName95(FileOpenDlgInfos *fodInfos)
     return lRes;
 }
 
-/***********************************************************************
- *      GetFileDialog95A
- *
- * Call GetFileName95 with this structure and clean the memory.
- *
- * IN  : The OPENFILENAMEA initialisation structure passed to
- *       GetOpenFileNameA win api function (see filedlg.c)
- */
-static BOOL GetFileDialog95A(LPOPENFILENAMEA ofn,UINT iDlgType)
+static WCHAR *heap_strdupAtoW(const char *str)
 {
-  BOOL ret;
-  FileOpenDlgInfos fodInfos;
-  LPSTR lpstrSavDir = NULL;
-  LPWSTR title = NULL;
-  LPWSTR defext = NULL;
-  LPWSTR filter = NULL;
-  LPWSTR customfilter = NULL;
+    WCHAR *ret;
+    INT len;
 
-  /* Initialize CommDlgExtendedError() */
-  COMDLG32_SetCommDlgExtendedError(0);
+    if (!str)
+        return NULL;
 
-  /* Initialize FileOpenDlgInfos structure */
-  ZeroMemory(&fodInfos, sizeof(FileOpenDlgInfos));
+    len = MultiByteToWideChar(CP_ACP, 0, str, -1, 0, 0);
+    ret = MemAlloc(len * sizeof(WCHAR));
+    MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
 
-  /* Pass in the original ofn */
-  fodInfos.ofnInfos = (LPOPENFILENAMEW)ofn;
+    return ret;
+}
 
-  /* save current directory */
-  if (ofn->Flags & OFN_NOCHANGEDIR)
-  {
-     lpstrSavDir = MemAlloc(MAX_PATH);
-     GetCurrentDirectoryA(MAX_PATH, lpstrSavDir);
-  }
+static void init_filedlg_infoW(OPENFILENAMEW *ofn, FileOpenDlgInfos *info)
+{
+    INITCOMMONCONTROLSEX icc;
 
-  fodInfos.unicode = FALSE;
+    /* Initialize ComboBoxEx32 */
+    icc.dwSize = sizeof(icc);
+    icc.dwICC = ICC_USEREX_CLASSES;
+    InitCommonControlsEx(&icc);
 
-  /* convert all the input strings to unicode */
-  if(ofn->lpstrInitialDir)
-  {
-    DWORD len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrInitialDir, -1, NULL, 0 );
-    fodInfos.initdir = MemAlloc((len+1)*sizeof(WCHAR));
-    MultiByteToWideChar( CP_ACP, 0, ofn->lpstrInitialDir, -1, fodInfos.initdir, len);
-  }
-  else
-    fodInfos.initdir = NULL;
+    /* Initialize CommDlgExtendedError() */
+    COMDLG32_SetCommDlgExtendedError(0);
 
-  if(ofn->lpstrFile)
-  {
-    fodInfos.filename = MemAlloc(ofn->nMaxFile*sizeof(WCHAR));
-    MultiByteToWideChar( CP_ACP, 0, ofn->lpstrFile, -1, fodInfos.filename, ofn->nMaxFile);
-  }
-  else
-    fodInfos.filename = NULL;
+    memset(info, 0, sizeof(*info));
 
-  if(ofn->lpstrDefExt)
-  {
-    DWORD len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrDefExt, -1, NULL, 0 );
-    defext = MemAlloc((len+1)*sizeof(WCHAR));
-    MultiByteToWideChar( CP_ACP, 0, ofn->lpstrDefExt, -1, defext, len);
-  }
-  fodInfos.defext = defext;
+    /* Pass in the original ofn */
+    info->ofnInfos = ofn;
 
-  if(ofn->lpstrTitle)
-  {
-    DWORD len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrTitle, -1, NULL, 0 );
-    title = MemAlloc((len+1)*sizeof(WCHAR));
-    MultiByteToWideChar( CP_ACP, 0, ofn->lpstrTitle, -1, title, len);
-  }
-  fodInfos.title = title;
+    info->title = ofn->lpstrTitle;
+    info->defext = ofn->lpstrDefExt;
+    info->filter = ofn->lpstrFilter;
+    info->customfilter = ofn->lpstrCustomFilter;
 
-  if (ofn->lpstrFilter)
-  {
-    LPCSTR s;
-    int n, len;
-
-    /* filter is a list...  title\0ext\0......\0\0 */
-    s = ofn->lpstrFilter;
-    while (*s) s = s+strlen(s)+1;
-    s++;
-    n = s - ofn->lpstrFilter;
-    len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrFilter, n, NULL, 0 );
-    filter = MemAlloc(len*sizeof(WCHAR));
-    MultiByteToWideChar( CP_ACP, 0, ofn->lpstrFilter, n, filter, len );
-  }
-  fodInfos.filter = filter;
+    if (ofn->lpstrFile)
+    {
+        info->filename = MemAlloc(ofn->nMaxFile * sizeof(WCHAR));
+        lstrcpynW(info->filename, ofn->lpstrFile, ofn->nMaxFile);
+    }
 
-  /* convert lpstrCustomFilter */
-  if (ofn->lpstrCustomFilter)
-  {
-    LPCSTR s;
-    int n, len;
-
-    /* customfilter contains a pair of strings...  title\0ext\0 */
-    s = ofn->lpstrCustomFilter;
-    if (*s) s = s+strlen(s)+1;
-    if (*s) s = s+strlen(s)+1;
-    n = s - ofn->lpstrCustomFilter;
-    len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrCustomFilter, n, NULL, 0 );
-    customfilter = MemAlloc(len*sizeof(WCHAR));
-    MultiByteToWideChar( CP_ACP, 0, ofn->lpstrCustomFilter, n, customfilter, len );
-  }
-  fodInfos.customfilter = customfilter;
+    if (ofn->lpstrInitialDir)
+    {
+        DWORD len = ExpandEnvironmentStringsW(ofn->lpstrInitialDir, NULL, 0);
+        if (len)
+        {
+            info->initdir = MemAlloc(len * sizeof(WCHAR));
+            ExpandEnvironmentStringsW(ofn->lpstrInitialDir, info->initdir, len);
+        }
+    }
 
-  /* Initialize the dialog property */
-  fodInfos.DlgInfos.dwDlgProp = 0;
-  fodInfos.DlgInfos.hwndCustomDlg = NULL;
+    info->unicode = TRUE;
+}
 
-  switch(iDlgType)
-  {
-    case OPEN_DIALOG :
-      ret = GetFileName95(&fodInfos);
-      break;
-    case SAVE_DIALOG :
-      fodInfos.DlgInfos.dwDlgProp |= FODPROP_SAVEDLG;
-      ret = GetFileName95(&fodInfos);
-      break;
-    default :
-      ret = 0;
-  }
+static void init_filedlg_infoA(OPENFILENAMEA *ofn, FileOpenDlgInfos *info)
+{
+    OPENFILENAMEW ofnW;
+    int len;
 
-  if (lpstrSavDir)
-  {
-      SetCurrentDirectoryA(lpstrSavDir);
-      MemFree(lpstrSavDir);
-  }
+    ofnW = *(OPENFILENAMEW *)ofn;
 
-  MemFree(title);
-  MemFree(defext);
-  MemFree(filter);
-  MemFree(customfilter);
-  MemFree(fodInfos.initdir);
-  MemFree(fodInfos.filename);
+    ofnW.lpstrInitialDir = heap_strdupAtoW(ofn->lpstrInitialDir);
+    ofnW.lpstrDefExt = heap_strdupAtoW(ofn->lpstrDefExt);
+    ofnW.lpstrTitle = heap_strdupAtoW(ofn->lpstrTitle);
 
-  TRACE("selected file: %s\n",ofn->lpstrFile);
+    if (ofn->lpstrFile)
+    {
+        len = MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFile, ofn->nMaxFile, NULL, 0);
+        ofnW.lpstrFile = MemAlloc(len * sizeof(WCHAR));
+        MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFile, ofn->nMaxFile, ofnW.lpstrFile, len);
+        ofnW.nMaxFile = len;
+    }
 
-  return ret;
+    if (ofn->lpstrFilter)
+    {
+        LPCSTR s;
+        int n;
+
+        /* filter is a list...  title\0ext\0......\0\0 */
+        s = ofn->lpstrFilter;
+        while (*s) s = s+strlen(s)+1;
+        s++;
+        n = s - ofn->lpstrFilter;
+        len = MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFilter, n, NULL, 0);
+        ofnW.lpstrFilter = MemAlloc(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 = MemAlloc(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 */
+    MemFree((WCHAR *)ofnW.lpstrInitialDir);
+    MemFree((WCHAR *)ofnW.lpstrFile);
 }
 
 /***********************************************************************
- *      GetFileDialog95W
+ *      GetFileDialog95
  *
- * Copy the OPENFILENAMEW structure in a FileOpenDlgInfos structure.
  * Call GetFileName95 with this structure and clean the memory.
- *
  */
-static BOOL GetFileDialog95W(LPOPENFILENAMEW ofn,UINT iDlgType)
+static BOOL GetFileDialog95(FileOpenDlgInfos *info, UINT dlg_type)
 {
-  BOOL ret;
-  FileOpenDlgInfos fodInfos;
-  LPWSTR lpstrSavDir = NULL;
-
-  /* Initialize CommDlgExtendedError() */
-  COMDLG32_SetCommDlgExtendedError(0);
-
-  /* Initialize FileOpenDlgInfos structure */
-  ZeroMemory(&fodInfos, sizeof(FileOpenDlgInfos));
-
-  /*  Pass in the original ofn */
-  fodInfos.ofnInfos = ofn;
-
-  fodInfos.title = ofn->lpstrTitle;
-  fodInfos.defext = ofn->lpstrDefExt;
-  fodInfos.filter = ofn->lpstrFilter;
-  fodInfos.customfilter = ofn->lpstrCustomFilter;
+    WCHAR *current_dir = NULL;
+    BOOL ret;
 
-  /* 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;
-
-  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;
+    /* save current directory */
+    if (info->ofnInfos->Flags & OFN_NOCHANGEDIR)
+    {
+        current_dir = MemAlloc(MAX_PATH * sizeof(WCHAR));
+        GetCurrentDirectoryW(MAX_PATH, current_dir);
+    }
 
-  /* save current directory */
-  if (ofn->Flags & OFN_NOCHANGEDIR)
-  {
-     lpstrSavDir = MemAlloc(MAX_PATH*sizeof(WCHAR));
-     GetCurrentDirectoryW(MAX_PATH, lpstrSavDir);
-  }
+    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;
+    }
 
-  fodInfos.unicode = TRUE;
+    /* 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);
+        }
+    }
 
-  switch(iDlgType)
-  {
-  case OPEN_DIALOG :
-      ret = GetFileName95(&fodInfos);
-      break;
-  case SAVE_DIALOG :
-      fodInfos.DlgInfos.dwDlgProp |= FODPROP_SAVEDLG;
-      ret = GetFileName95(&fodInfos);
-      break;
-  default :
-      ret = 0;
-  }
+    if (current_dir)
+    {
+        SetCurrentDirectoryW(current_dir);
+        MemFree(current_dir);
+    }
 
-  if (lpstrSavDir)
-  {
-      SetCurrentDirectoryW(lpstrSavDir);
-      MemFree(lpstrSavDir);
-  }
+    if (!info->unicode)
+    {
+        MemFree((WCHAR *)info->defext);
+        MemFree((WCHAR *)info->title);
+        MemFree((WCHAR *)info->filter);
+        MemFree((WCHAR *)info->customfilter);
+    }
 
-  /* restore saved IN arguments and convert OUT arguments back */
-  MemFree(fodInfos.filename);
-  MemFree(fodInfos.initdir);
-  return ret;
+    MemFree(info->filename);
+    MemFree(info->initdir);
+    return ret;
 }
 
 /******************************************************************************
@@ -647,7 +595,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++;
@@ -839,7 +787,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
@@ -926,39 +874,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;
 }
 
@@ -966,7 +905,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");
 
@@ -1006,7 +945,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;
 
@@ -1089,7 +1028,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)
     {
@@ -1117,11 +1056,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) ||
@@ -1158,8 +1097,9 @@ static LRESULT FILEDLG95_OnWMSize(HWND hwnd, WPARAM wParam)
              * move to bottom */
             switch( ctrlid)
             {
-                /* file name box and file types combo change also width */
+                /* file name (edit or comboboxex) and file types combo change also width */
                 case edt1:
+                case cmb13:
                 case cmb1:
                     DeferWindowPos( hdwp, ctrl, NULL, rc.left, rc.top + chgy,
                             rc.right - rc.left + chgx, rc.bottom - rc.top,
@@ -1273,15 +1213,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 |
@@ -1361,10 +1327,10 @@ 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);
           if (fodInfos && fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)
               MemDialogSize = fodInfos->sizedlg;
-          RemovePropA(hwnd, FileOpenDlgInfosStr);
+          RemovePropW(hwnd, filedlg_info_propnameW);
           return FALSE;
       }
     case WM_NOTIFY:
@@ -1413,6 +1379,12 @@ INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
   }
 }
 
+static inline BOOL filename_is_edit( const FileOpenDlgInfos *info )
+{
+    return (info->ofnInfos->lStructSize == OPENFILENAME_SIZE_VERSION_400W) &&
+        (info->ofnInfos->Flags & (OFN_ENABLEHOOK | OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE));
+}
+
 /***********************************************************************
  *      FILEDLG95_InitControls
  *
@@ -1420,9 +1392,9 @@ INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
  */
 static LRESULT FILEDLG95_InitControls(HWND hwnd)
 {
-  int win2000plus = 0;
-  int win98plus   = 0;
-  int handledPath = FALSE;
+  BOOL win2000plus = FALSE;
+  BOOL win98plus   = FALSE;
+  BOOL handledPath = FALSE;
   OSVERSIONINFOW osVi;
   static const WCHAR szwSlash[] = { '\\', 0 };
   static const WCHAR szwStar[] = { '*',0 };
@@ -1448,7 +1420,7 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
   SHFILEINFOA shFileInfo;
   ITEMIDLIST *desktopPidl;
 
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
 
   TRACE("%p\n", fodInfos);
 
@@ -1463,8 +1435,20 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
   }
   TRACE("Running on 2000+ %d, 98+ %d\n", win2000plus, win98plus);
 
+
+  /* Use either the edit or the comboboxex for the filename control */
+  if (filename_is_edit( fodInfos ))
+  {
+      DestroyWindow( GetDlgItem( hwnd, cmb13 ) );
+      fodInfos->DlgInfos.hwndFileName = GetDlgItem( hwnd, edt1 );
+  }
+  else
+  {
+      DestroyWindow( GetDlgItem( hwnd, edt1 ) );
+      fodInfos->DlgInfos.hwndFileName = GetDlgItem( hwnd, cmb13 );
+  }
+
   /* Get the hwnd of the controls */
-  fodInfos->DlgInfos.hwndFileName = GetDlgItem(hwnd,IDC_FILENAME);
   fodInfos->DlgInfos.hwndFileTypeCB = GetDlgItem(hwnd,IDC_FILETYPE);
   fodInfos->DlgInfos.hwndLookInCB = GetDlgItem(hwnd,IDC_LOOKIN);
 
@@ -1542,10 +1526,16 @@ 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));
             lstrcpyW(fodInfos->initdir, tmpBuf);
@@ -1553,56 +1543,50 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
             TRACE("Value in Filename includes path, overriding InitialDir: %s, %s\n",
                     debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
          }
-         SetDlgItemTextW(hwnd, IDC_FILENAME, fodInfos->filename);
+         SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename );
 
       } else {
-         SetDlgItemTextW(hwnd, IDC_FILENAME, fodInfos->filename);
+         SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename );
       }
   }
 
   /* 2. (All platforms) If initdir is not null, then use it */
-  if ((handledPath == FALSE) && (fodInfos->initdir!=NULL) &&
-                                (*fodInfos->initdir!=0x00))
+  if (!handledPath && fodInfos->initdir && *fodInfos->initdir)
   {
-      /* Work out the proper path as supplied one might be relative          */
-      /* (Here because supplying '.' as dir browses to My Computer)          */
-      if (handledPath==FALSE) {
-          WCHAR tmpBuf[MAX_PATH];
-          WCHAR tmpBuf2[MAX_PATH];
-          WCHAR *nameBit;
-          DWORD result;
-
-          lstrcpyW(tmpBuf, fodInfos->initdir);
-          if( PathFileExistsW(tmpBuf) ) {
-              /* initdir does not have to be a directory. If a file is
-               * specified, the dir part is taken */
-              if( PathIsDirectoryW(tmpBuf)) {
-                  if (tmpBuf[lstrlenW(tmpBuf)-1] != '\\') {
-                     lstrcatW(tmpBuf, szwSlash);
-                  }
-                  lstrcatW(tmpBuf, szwStar);
-              }
-              result = GetFullPathNameW(tmpBuf, MAX_PATH, tmpBuf2, &nameBit);
-              if (result) {
-                 *nameBit = 0x00;
-                 MemFree(fodInfos->initdir);
-                 fodInfos->initdir = MemAlloc((lstrlenW(tmpBuf2) + 1)*sizeof(WCHAR));
-                 lstrcpyW(fodInfos->initdir, tmpBuf2);
-                 handledPath = TRUE;
-                 TRACE("Value in InitDir changed to %s\n", debugstr_w(fodInfos->initdir));
-              }
-          }
-          else if (fodInfos->initdir)
-          {
-                    MemFree(fodInfos->initdir);
-                    fodInfos->initdir = NULL;
-                    TRACE("Value in InitDir is not an existing path, changed to (nil)\n");
-          }
-      }
+        /* Work out the proper path as supplied one might be relative          */
+        /* (Here because supplying '.' as dir browses to My Computer)          */
+        WCHAR tmpBuf[MAX_PATH];
+        WCHAR tmpBuf2[MAX_PATH];
+        WCHAR *nameBit;
+        DWORD result;
+
+        lstrcpyW(tmpBuf, fodInfos->initdir);
+        if (PathFileExistsW(tmpBuf)) {
+            /* initdir does not have to be a directory. If a file is
+             * specified, the dir part is taken */
+            if (PathIsDirectoryW(tmpBuf)) {
+                PathAddBackslashW(tmpBuf);
+                lstrcatW(tmpBuf, szwStar);
+            }
+            result = GetFullPathNameW(tmpBuf, MAX_PATH, tmpBuf2, &nameBit);
+            if (result) {
+                *nameBit = 0x00;
+                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");
+        }
   }
 
-  if ((handledPath == FALSE) && ((fodInfos->initdir==NULL) ||
-                                 (*fodInfos->initdir==0x00)))
+  if (!handledPath && (!fodInfos->initdir || !*fodInfos->initdir))
   {
       /* 3. All except w2k+: if filename contains a path use it */
       if (!win2000plus && fodInfos->filename &&
@@ -1630,11 +1614,11 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
             TRACE("Value in Filename includes path, overriding initdir: %s, %s\n",
                  debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
          }
-         SetDlgItemTextW(hwnd, IDC_FILENAME, fodInfos->filename);
+         SetWindowTextW( fodInfos->DlgInfos.hwndFileName, fodInfos->filename );
       }
 
       /* 4. Win2000+: Recently used */
-      if (handledPath == FALSE && win2000plus) {
+      if (!handledPath && win2000plus) {
           fodInfos->initdir = MemAlloc(MAX_PATH * sizeof(WCHAR));
           fodInfos->initdir[0] = '\0';
 
@@ -1650,8 +1634,7 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
 
       /* 5. win98+ and win2000+ if any files of specified filter types in
             current directory, use it                                      */
-      if ( win98plus && handledPath == FALSE &&
-           fodInfos->filter && *fodInfos->filter) {
+      if (win98plus && !handledPath && fodInfos->filter && *fodInfos->filter) {
 
          LPCWSTR lpstrPos = fodInfos->filter;
          WIN32_FIND_DATAW FindFileData;
@@ -1690,7 +1673,7 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
       }
 
       /* 6. Win98+ and 2000+: Use personal files dir, others use current dir */
-      if (handledPath == FALSE && (win2000plus || win98plus)) {
+      if (!handledPath && (win2000plus || win98plus)) {
           fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR));
 
           if(!COMDLG32_SHGetFolderPathW(hwnd, CSIDL_PERSONAL, 0, 0, fodInfos->initdir))
@@ -1707,14 +1690,14 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
             TRACE("No initial dir specified, using personal files dir of %s\n", debugstr_w(fodInfos->initdir));
           }
           handledPath = TRUE;
-      } else if (handledPath==FALSE) {
+      } else if (!handledPath) {
           fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR));
           GetCurrentDirectoryW(MAX_PATH, fodInfos->initdir);
           handledPath = TRUE;
           TRACE("No initial dir specified, using current dir of %s\n", debugstr_w(fodInfos->initdir));
       }
   }
-  SetFocus(GetDlgItem(hwnd, IDC_FILENAME));
+  SetFocus( fodInfos->DlgInfos.hwndFileName );
   TRACE("After manipulation, file = %s, dir = %s\n", debugstr_w(fodInfos->filename), debugstr_w(fodInfos->initdir));
 
   /* Must the open as read only check box be checked ?*/
@@ -1781,12 +1764,12 @@ static LRESULT FILEDLG95_ResizeControls(HWND hwnd, WPARAM wParam, LPARAM lParam)
       flags |= SWP_NOSIZE;
       SetRectEmpty(&rc);
     }
-      SetWindowPos(fodInfos->DlgInfos.hwndCustomDlg, HWND_BOTTOM,
-          0, 0, rc.right, rc.bottom, flags);
+    SetWindowPos(fodInfos->DlgInfos.hwndCustomDlg, HWND_BOTTOM,
+                 0, 0, rc.right, rc.bottom, flags);
   }
   else
   {
-    /* Resize the height, if open as read only checkbox ad help button are
+    /* Resize the height; if opened as read-only, checkbox and help button are
      * hidden and we are not using a custom template nor a customDialog
      */
     if ( (fodInfos->ofnInfos->Flags & OFN_HIDEREADONLY) &&
@@ -1864,9 +1847,9 @@ 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);
 
   switch(wID)
   {
@@ -1910,7 +1893,8 @@ static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam)
     FILEDLG95_SHELL_BrowseToDesktop(hwnd);
     break;
 
-  case IDC_FILENAME:
+  case edt1:
+  case cmb13:
     break;
 
   }
@@ -1926,7 +1910,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");
 
@@ -1984,9 +1968,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");
 
@@ -2413,6 +2397,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;
@@ -2420,7 +2405,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);
 
@@ -2524,6 +2508,7 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
                 && fodInfos->ofnInfos->Flags & OFN_EXPLORER)
             {
               SendCustomDlgNotificationMessage(hwnd, CDN_FOLDERCHANGE);
+              SendMessageA(fodInfos->DlgInfos.hwndFileName, WM_SETTEXT, 0, (LPARAM)"");
             }
          }
          else if( nOpenAction == ONOPEN_SEARCH )
@@ -2532,7 +2517,15 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
               IShellView_Refresh(fodInfos->Shell.FOIShellView);
          }
           COMDLG32_SHFree(pidlCurrent);
-          SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1);
+          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;
@@ -2550,12 +2543,12 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
 
         /* Attach the file extension with file name*/
         ext = PathFindExtensionW(lpstrPathAndFile);
-        if (! *ext)
+        if (! *ext && fodInfos->defext)
         {
             /* if no extension is specified with file name, then */
             /* attach the extension from file filter or default one */
             
-            const WCHAR *filterExt = NULL;
+            WCHAR *filterExt = NULL;
             LPWSTR lpstrFilter = NULL;
             static const WCHAR szwDot[] = {'.',0};
             int PathLength = lstrlenW(lpstrPathAndFile);
@@ -2565,36 +2558,63 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
                                              fodInfos->ofnInfos->nFilterIndex-1);
 
             if (lpstrFilter != (LPWSTR)CB_ERR)  /* control is not empty */
-                filterExt = PathFindExtensionW(lpstrFilter);
+            {
+                WCHAR* filterSearchIndex;
+                filterExt = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(lpstrFilter) + 1) * sizeof(WCHAR));
+                strcpyW(filterExt, lpstrFilter);
+
+                /* if a semicolon-separated list of file extensions was given, do not include the
+                   semicolon or anything after it in the extension.
+                   example: if filterExt was "*.abc;*.def", it will become "*.abc" */
+                filterSearchIndex = strchrW(filterExt, ';');
+                if (filterSearchIndex)
+                {
+                    filterSearchIndex[0] = '\0';
+                }
+
+                /* find the file extension by searching for the first dot in filterExt */
+                /* strip the * or anything else from the extension, "*.abc" becomes "abc" */
+                /* if the extension is invalid or contains a glob, ignore it */
+                filterSearchIndex = strchrW(filterExt, '.');
+                if (filterSearchIndex++ && !strchrW(filterSearchIndex, '*') && !strchrW(filterSearchIndex, '?'))
+                {
+                    strcpyW(filterExt, filterSearchIndex);
+                }
+                else
+                {
+                    HeapFree(GetProcessHeap(), 0, filterExt);
+                    filterExt = NULL;
+                }
+            }
 
-            if ( filterExt && *filterExt ) /* attach the file extension from file type filter*/
-                filterExt = filterExt + 1;
-            else if ( fodInfos->defext ) /* attach the default file extension*/
-                filterExt = fodInfos->defext;
+            if (!filterExt)
+            {
+                /* use the default file extension */
+                filterExt = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(fodInfos->defext) + 1) * sizeof(WCHAR));
+                strcpyW(filterExt, fodInfos->defext);
+            }
 
-            /* If extension contains a glob, ignore it */
-            if ( filterExt && !strchrW(filterExt, '*') && !strchrW(filterExt, '?') )
+            if (*filterExt) /* ignore filterExt="" */
             {
                 /* Attach the dot*/
                 lstrcatW(lpstrPathAndFile, szwDot);
                 /* Attach the extension */
-                lstrcatW(lpstrPathAndFile, filterExt );
+                lstrcatW(lpstrPathAndFile, filterExt);
             }
 
+            HeapFree(GetProcessHeap(), 0, filterExt);
+
             /* In Open dialog: if file does not exist try without extension */
             if (!(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG) && !PathFileExistsW(lpstrPathAndFile))
                   lpstrPathAndFile[PathLength] = '\0';
-        }
 
-       if (fodInfos->defext) /* add default extension */
-       {
-         /* Set/clear the output OFN_EXTENSIONDIFFERENT flag */
-         if (*ext)
-           ext++;
-         if (!lstrcmpiW(fodInfos->defext, ext))
-           fodInfos->ofnInfos->Flags &= ~OFN_EXTENSIONDIFFERENT;
-         else
-           fodInfos->ofnInfos->Flags |= OFN_EXTENSIONDIFFERENT;
+            /* Set/clear the output OFN_EXTENSIONDIFFERENT flag */
+            if (*ext)
+                ext++;
+            if (!lstrcmpiW(fodInfos->defext, ext))
+                fodInfos->ofnInfos->Flags &= ~OFN_EXTENSIONDIFFERENT;
+            else
+                fodInfos->ofnInfos->Flags |= OFN_EXTENSIONDIFFERENT;
        }
 
        /* In Save dialog: check if the file already exists */
@@ -2675,35 +2695,22 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
           }
           else
           {
-               LPSTR lpszTemp;
-               LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)fodInfos->ofnInfos;
+              LPSTR lpszTemp;
+              CHAR tempFileA[MAX_PATH];
+
+              /* avoid using fodInfos->ofnInfos->lpstrFile since it can be NULL */
+              WideCharToMultiByte(CP_ACP, 0, lpstrPathAndFile, -1,
+                                  tempFileA, sizeof(tempFileA), NULL, NULL);
 
               /* set filename offset */
-              lpszTemp = PathFindFileNameA(ofn->lpstrFile);
-              fodInfos->ofnInfos->nFileOffset = (lpszTemp - ofn->lpstrFile);
+              lpszTemp = PathFindFileNameA(tempFileA);
+              fodInfos->ofnInfos->nFileOffset = (lpszTemp - tempFileA);
 
               /* set extension offset */
-              lpszTemp = PathFindExtensionA(ofn->lpstrFile);
-              fodInfos->ofnInfos->nFileExtension = (*lpszTemp) ? (lpszTemp - ofn->lpstrFile) + 1 : 0;
+              lpszTemp = PathFindExtensionA(tempFileA);
+              fodInfos->ofnInfos->nFileExtension = (*lpszTemp) ? (lpszTemp - tempFileA) + 1 : 0;
           }
 
-          /* set the lpstrFileTitle */
-          if(fodInfos->ofnInfos->lpstrFileTitle)
-         {
-            LPWSTR lpstrFileTitle = PathFindFileNameW(lpstrPathAndFile);
-            if(fodInfos->unicode)
-            {
-              LPOPENFILENAMEW ofn = fodInfos->ofnInfos;
-             lstrcpynW(ofn->lpstrFileTitle, lpstrFileTitle, ofn->nMaxFileTitle);
-            }
-            else
-            {
-              LPOPENFILENAMEA ofn = (LPOPENFILENAMEA)fodInfos->ofnInfos;
-              WideCharToMultiByte(CP_ACP, 0, lpstrFileTitle, -1,
-                    ofn->lpstrFileTitle, ofn->nMaxFileTitle, NULL, NULL);
-            }
-         }
-
           /* copy currently selected filter to lpstrCustomFilter */
           if (fodInfos->ofnInfos->lpstrCustomFilter)
           {
@@ -2737,7 +2744,8 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
           if (fodInfos->ofnInfos->Flags & OFN_ALLOWMULTISELECT)
              size += 1;
           /* return needed size in first two bytes of lpstrFile */
-          *(WORD *)fodInfos->ofnInfos->lpstrFile = size;
+          if(fodInfos->ofnInfos->lpstrFile)
+              *(WORD *)fodInfos->ofnInfos->lpstrFile = size;
           FILEDLG95_Clean(hwnd);
           ret = EndDialog(hwnd, FALSE);
           COMDLG32_SetCommDlgExtendedError(FNERR_BUFFERTOOSMALL);
@@ -2758,9 +2766,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
@@ -2793,7 +2801,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);
@@ -2824,7 +2832,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");
 
@@ -2847,7 +2855,7 @@ static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd)
  */
 static BOOL FILEDLG95_SHELL_BrowseToDesktop(HWND hwnd)
 {
-  FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+  FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
   LPITEMIDLIST pidl;
   HRESULT hres;
 
@@ -2867,7 +2875,7 @@ 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");
 
@@ -2879,7 +2887,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);
@@ -2892,11 +2901,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)
   {
@@ -3007,7 +3016,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)
   {
@@ -3074,7 +3083,7 @@ 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);
 
@@ -3125,19 +3134,25 @@ static void FILEDLG95_LOOKIN_Init(HWND hwndCombo)
   IShellFolder *psfRoot, *psfDrives;
   IEnumIDList  *lpeRoot, *lpeDrives;
   LPITEMIDLIST pidlDrives, pidlTmp, pidlTmp1, pidlAbsTmp;
-
+  HDC hdc;
+  TEXTMETRICW tm;
   LookInInfos *liInfos = MemAlloc(sizeof(LookInInfos));
 
-  TRACE("\n");
+  TRACE("%p\n", hwndCombo);
 
   liInfos->iMaxIndentation = 0;
 
   SetPropA(hwndCombo, LookInInfosStr, liInfos);
 
+  hdc = GetDC( hwndCombo );
+  SelectObject( hdc, (HFONT)SendMessageW( hwndCombo, WM_GETFONT, 0, 0 ));
+  GetTextMetricsW( hdc, &tm );
+  ReleaseDC( hwndCombo, hdc );
+
   /* set item height for both text field and listbox */
-  CBSetItemHeight(hwndCombo,-1,GetSystemMetrics(SM_CYSMICON));
-  CBSetItemHeight(hwndCombo,0,GetSystemMetrics(SM_CYSMICON));
-   
+  CBSetItemHeight( hwndCombo, -1, max( tm.tmHeight, GetSystemMetrics(SM_CYSMICON) ));
+  CBSetItemHeight( hwndCombo, 0, max( tm.tmHeight, GetSystemMetrics(SM_CYSMICON) ));
+
   /* Turn on the extended UI for the combo box like Windows does */
   CBSetExtendedUI(hwndCombo, TRUE);
 
@@ -3211,7 +3226,8 @@ static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct)
   int iIndentation;
   TEXTMETRICW tm;
   LPSFOLDER tmpFolder;
-  LookInInfos *liInfos = GetPropA(pDIStruct->hwndItem,LookInInfosStr);
+  UINT shgfi_flags = SHGFI_PIDL | SHGFI_OPENICON | SHGFI_SYSICONINDEX | SHGFI_DISPLAYNAME;
+  UINT icon_width, icon_height;
 
   TRACE("\n");
 
@@ -3223,27 +3239,18 @@ static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct)
     return 0;
 
 
-  if(pDIStruct->itemID == liInfos->uSelectedItem)
-  {
-    ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
-                                               0,
-                                               &sfi,
-                                               sizeof (sfi),
-                                               SHGFI_PIDL | SHGFI_SMALLICON |
-                                               SHGFI_OPENICON | SHGFI_SYSICONINDEX    |
-                                               SHGFI_DISPLAYNAME );
-  }
-  else
+  icon_width = GetSystemMetrics(SM_CXICON);
+  icon_height = GetSystemMetrics(SM_CYICON);
+  if (pDIStruct->rcItem.bottom - pDIStruct->rcItem.top < icon_height)
   {
-    ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
-                                                  0,
-                                                  &sfi,
-                                                  sizeof (sfi),
-                                                  SHGFI_PIDL | SHGFI_SMALLICON |
-                                                  SHGFI_SYSICONINDEX |
-                                                  SHGFI_DISPLAYNAME);
+      icon_width = GetSystemMetrics(SM_CXSMICON);
+      icon_height = GetSystemMetrics(SM_CYSMICON);
+      shgfi_flags |= SHGFI_SMALLICON;
   }
 
+  ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
+                                             0, &sfi, sizeof (sfi), shgfi_flags );
+
   /* Is this item selected ? */
   if(pDIStruct->itemState & ODS_SELECTED)
   {
@@ -3260,34 +3267,24 @@ static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct)
 
   /* Do not indent item if drawing in the edit of the combo */
   if(pDIStruct->itemState & ODS_COMBOBOXEDIT)
-  {
     iIndentation = 0;
-    ilItemImage = (HIMAGELIST) SHGetFileInfoW ((LPCWSTR) tmpFolder->pidlItem,
-                                                0,
-                                                &sfi,
-                                                sizeof (sfi),
-                                                SHGFI_PIDL | SHGFI_SMALLICON | SHGFI_OPENICON
-                                                | SHGFI_SYSICONINDEX | SHGFI_DISPLAYNAME  );
-
-  }
   else
-  {
     iIndentation = tmpFolder->m_iIndent;
-  }
+
   /* Draw text and icon */
 
   /* Initialise the icon display area */
-  rectIcon.left = pDIStruct->rcItem.left + ICONWIDTH/2 * iIndentation;
-  rectIcon.top = pDIStruct->rcItem.top;
-  rectIcon.right = rectIcon.left + ICONWIDTH;
-  rectIcon.bottom = pDIStruct->rcItem.bottom;
+  rectIcon.left = pDIStruct->rcItem.left + 1 + icon_width/2 * iIndentation;
+  rectIcon.top = (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom - icon_height) / 2;
+  rectIcon.right = rectIcon.left + icon_width + XTEXTOFFSET;
+  rectIcon.bottom = (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom + icon_height) / 2;
 
   /* Initialise the text display area */
   GetTextMetricsW(pDIStruct->hDC, &tm);
   rectText.left = rectIcon.right;
   rectText.top =
          (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom - tm.tmHeight) / 2;
-  rectText.right = pDIStruct->rcItem.right + XTEXTOFFSET;
+  rectText.right = pDIStruct->rcItem.right;
   rectText.bottom =
          (pDIStruct->rcItem.top + pDIStruct->rcItem.bottom + tm.tmHeight) / 2;
 
@@ -3312,7 +3309,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);
 
@@ -3360,7 +3357,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;
@@ -3388,10 +3385,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))
   {
@@ -3460,7 +3456,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);
 
@@ -3558,7 +3554,7 @@ 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);
@@ -3582,6 +3578,25 @@ static void FILEDLG95_LOOKIN_Clean(HWND hwnd)
     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
  *
@@ -3589,85 +3604,73 @@ static void FILEDLG95_LOOKIN_Clean(HWND hwnd)
  */
 void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd)
 {
-    FileOpenDlgInfos *fodInfos;
+    FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
     LPITEMIDLIST      pidl;
-    UINT              nFiles = 0, nFileToOpen, nFileSelected, nLength = 0;
-    WCHAR             lpstrTemp[MAX_PATH];
-    LPWSTR            lpstrAllFile, lpstrCurrFile;
+    LPWSTR            lpstrAllFiles, lpstrTmp;
+    UINT nFiles = 0, nFileToOpen, nFileSelected, nAllFilesLength = 0, nThisFileLength, nAllFilesMaxLength;
+    STGMEDIUM medium;
+    LPIDA cida;
+    FORMATETC formatetc = get_def_format();
 
     TRACE("\n");
-    fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
-
-    /* Count how many files we have */
-    nFileSelected = GetNumSelected( fodInfos->Shell.FOIDataObject );
-
-    /* calculate the string length, count files */
-    if (nFileSelected >= 1)
-    {
-      nLength += 3;    /* first and last quotes, trailing \0 */
-      for ( nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++ )
-      {
-        pidl = GetPidlFromDataObject( fodInfos->Shell.FOIDataObject, nFileToOpen+1 );
 
-        if (pidl)
-       {
-          /* get the total length of the selected file names */
-          lpstrTemp[0] = '\0';
-          GetName( fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER|SHGDN_FORPARSING, lpstrTemp );
+    if (FAILED(IDataObject_GetData(fodInfos->Shell.FOIDataObject, &formatetc, &medium)))
+        return;
 
-          if ( ! IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl) ) /* Ignore folders */
-         {
-            nLength += lstrlenW( lpstrTemp ) + 3;
-            nFiles++;
-         }
-          COMDLG32_SHFree( pidl );
-       }
-      }
-    }
+    cida = GlobalLock(medium.u.hGlobal);
+    nFileSelected = cida->cidl;
 
-    /* allocate the buffer */
-    if (nFiles <= 1) nLength = MAX_PATH;
-    lpstrAllFile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nLength * sizeof(WCHAR));
+    /* Allocate a buffer */
+    nAllFilesMaxLength = MAX_PATH + 3;
+    lpstrAllFiles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nAllFilesMaxLength * sizeof(WCHAR));
+    if (!lpstrAllFiles)
+        goto ret;
 
-    /* Generate the string for the edit control */
-    if(nFiles >= 1)
+    /* Loop through the selection, handle only files (not folders) */
+    for (nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++)
     {
-      lpstrCurrFile = lpstrAllFile;
-      for ( nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++ )
-      {
-        pidl = GetPidlFromDataObject( fodInfos->Shell.FOIDataObject, nFileToOpen+1 );
-
+        pidl = (LPITEMIDLIST)((LPBYTE)cida + cida->aoffset[nFileToOpen + 1]);
         if (pidl)
-       {
-         /* get the file name */
-          lpstrTemp[0] = '\0';
-          GetName( fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER|SHGDN_FORPARSING, lpstrTemp );
+        {
+            if (!IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl))
+            {
+                if (nAllFilesLength + MAX_PATH + 3 > nAllFilesMaxLength)
+                {
+                    nAllFilesMaxLength *= 2;
+                    lpstrTmp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpstrAllFiles, nAllFilesMaxLength * sizeof(WCHAR));
+                    if (!lpstrTmp)
+                        goto ret;
+                    lpstrAllFiles = lpstrTmp;
+                }
+                nFiles += 1;
+                lpstrAllFiles[nAllFilesLength++] = '"';
+                GetName(fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING, lpstrAllFiles + nAllFilesLength);
+                nThisFileLength = lstrlenW(lpstrAllFiles + nAllFilesLength);
+                nAllFilesLength += nThisFileLength;
+                lpstrAllFiles[nAllFilesLength++] = '"';
+                lpstrAllFiles[nAllFilesLength++] = ' ';
+            }
+        }
+    }
 
-          if (! IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl)) /* Ignore folders */
-         {
-            if ( nFiles > 1)
-           {
-              *lpstrCurrFile++ =  '\"';
-              lstrcpyW( lpstrCurrFile, lpstrTemp );
-              lpstrCurrFile += lstrlenW( lpstrTemp );
-              *lpstrCurrFile++ = '\"';
-              *lpstrCurrFile++ = ' ';
-              *lpstrCurrFile = 0;
-           }
-           else
-           {
-              lstrcpyW( lpstrAllFile, lpstrTemp );
-           }
-          }
-          COMDLG32_SHFree( pidl );
-       }
-      }
-      SetWindowTextW( fodInfos->DlgInfos.hwndFileName, lpstrAllFile );
-       
-      /* Select the file name like Windows does */ 
-      SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1);
+    if (nFiles != 0)
+    {
+        /* If there's only one file, use the name as-is without quotes */
+        lpstrTmp = lpstrAllFiles;
+        if (nFiles == 1)
+        {
+            lpstrTmp += 1;
+            lpstrTmp[nThisFileLength] = 0;
+        }
+        SetWindowTextW(fodInfos->DlgInfos.hwndFileName, lpstrTmp);
+        /* Select the file name like Windows does */
+        if (filename_is_edit(fodInfos))
+            SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1);
     }
-    HeapFree(GetProcessHeap(),0, lpstrAllFile );
+
+ret:
+    HeapFree(GetProcessHeap(), 0, lpstrAllFiles);
+    COMCTL32_ReleaseStgMedium(medium);
 }
 
 
@@ -3709,17 +3712,17 @@ static HRESULT COMDLG32_StrRetToStrNW (LPWSTR dest, DWORD len, LPSTRRET src, con
  */
 static int FILEDLG95_FILENAME_GetFileNames (HWND hwnd, LPWSTR * lpstrFileList, UINT * sizeUsed)
 {
-       FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
+       FileOpenDlgInfos *fodInfos = get_filedlg_infoptr(hwnd);
        UINT nFileCount = 0;    /* number of files */
        UINT nStrLen = 0;       /* length of string in edit control */
        LPWSTR lpstrEdit;       /* buffer for string from edit control */
 
        TRACE("\n");
 
-       /* get the filenames from the edit control */
-       nStrLen = SendMessageW(fodInfos->DlgInfos.hwndFileName, WM_GETTEXTLENGTH, 0, 0);
+       /* get the filenames from the filename control */
+       nStrLen = GetWindowTextLengthW( fodInfos->DlgInfos.hwndFileName );
        lpstrEdit = MemAlloc( (nStrLen+1)*sizeof(WCHAR) );
-       GetDlgItemTextW(hwnd, IDC_FILENAME, lpstrEdit, nStrLen+1);
+       GetWindowTextW( fodInfos->DlgInfos.hwndFileName, lpstrEdit, nStrLen+1);
 
        TRACE("nStrLen=%u str=%s\n", nStrLen, debugstr_w(lpstrEdit));
 
@@ -3728,15 +3731,6 @@ static int FILEDLG95_FILENAME_GetFileNames (HWND hwnd, LPWSTR * lpstrFileList, U
        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
  */
@@ -3770,16 +3764,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)))
@@ -3804,15 +3795,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)))
     {
@@ -3958,8 +3946,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");
 
@@ -3974,9 +3962,9 @@ 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, sizeof(buf)/sizeof(WCHAR) );
+               MessageBoxW( hwnd, buf, fodInfos->title, MB_OK | MB_ICONEXCLAMATION );
           }
           bBrowseSelFolder = TRUE;
           if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
@@ -4000,186 +3988,16 @@ static void MemFree(void *mem)
     HeapFree(GetProcessHeap(),0,mem);
 }
 
-/*
- * Old-style (win3.1) dialogs */
-
-/***********************************************************************
- *           FD32_GetTemplate                                  [internal]
- *
- * Get a template (or FALSE if failure) when 16 bits dialogs are used
- * by a 32 bits application
- *
- */
-BOOL FD32_GetTemplate(PFD31_DATA lfs)
+static inline BOOL valid_struct_size( DWORD size )
 {
-    LPOPENFILENAMEW ofnW = lfs->ofnW;
-    LPOPENFILENAMEA ofnA = lfs->ofnA;
-    HANDLE hDlgTmpl;
-
-    if (ofnW->Flags & OFN_ENABLETEMPLATEHANDLE)
-    {
-       if (!(lfs->template = LockResource( ofnW->hInstance )))
-       {
-           COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
-           return FALSE;
-       }
-    }
-    else if (ofnW->Flags & OFN_ENABLETEMPLATE)
-    {
-       HRSRC hResInfo;
-        if (ofnA)
-           hResInfo = FindResourceA(ofnA->hInstance,
-                                ofnA->lpTemplateName,
-                                 (LPSTR)RT_DIALOG);
-        else
-           hResInfo = FindResourceW(ofnW->hInstance,
-                                ofnW->lpTemplateName,
-                                 (LPWSTR)RT_DIALOG);
-        if (!hResInfo)
-       {
-           COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
-           return FALSE;
-       }
-       if (!(hDlgTmpl = LoadResource(ofnW->hInstance,
-                               hResInfo)) ||
-                   !(lfs->template = LockResource(hDlgTmpl)))
-       {
-           COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
-           return FALSE;
-       }
-    } else { /* get it from internal Wine resource */
-       HRSRC hResInfo;
-       if (!(hResInfo = FindResourceA(COMDLG32_hInstance,
-             lfs->open? "OPEN_FILE":"SAVE_FILE", (LPSTR)RT_DIALOG)))
-       {
-           COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
-           return FALSE;
-        }
-        if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo )) ||
-                !(lfs->template = LockResource( hDlgTmpl )))
-        {
-            COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
-            return FALSE;
-        }
-    }
-    return TRUE;
+    return (size == OPENFILENAME_SIZE_VERSION_400W) ||
+        (size == sizeof( OPENFILENAMEW ));
 }
 
-
-/***********************************************************************
- *                              FD32_WMMeasureItem           [internal]
- */
-static LONG FD32_WMMeasureItem(LPARAM lParam)
+static inline BOOL is_win16_looks(DWORD flags)
 {
-    LPMEASUREITEMSTRUCT lpmeasure;
-
-    lpmeasure = (LPMEASUREITEMSTRUCT)lParam;
-    lpmeasure->itemHeight = FD31_GetFldrHeight();
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           FileOpenDlgProc                                    [internal]
- *      Used for open and save, in fact.
- */
-static INT_PTR CALLBACK FD32_FileOpenDlgProc(HWND hWnd, UINT wMsg,
-                                             WPARAM wParam, LPARAM lParam)
-{
-    PFD31_DATA lfs = (PFD31_DATA)GetPropA(hWnd,FD31_OFN_PROP);
-
-    TRACE("msg=%x wparam=%lx lParam=%lx\n", wMsg, wParam, lParam);
-    if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook)
-        {
-            INT_PTR lRet;
-            lRet  = (INT_PTR)FD31_CallWindowProc(lfs, wMsg, wParam, lParam);
-            if (lRet)
-                return lRet;         /* else continue message processing */
-        }
-    switch (wMsg)
-    {
-    case WM_INITDIALOG:
-        return FD31_WMInitDialog(hWnd, wParam, lParam);
-
-    case WM_MEASUREITEM:
-        return FD32_WMMeasureItem(lParam);
-
-    case WM_DRAWITEM:
-        return FD31_WMDrawItem(hWnd, wParam, lParam, !lfs->open, (DRAWITEMSTRUCT *)lParam);
-
-    case WM_COMMAND:
-        return FD31_WMCommand(hWnd, lParam, HIWORD(wParam), LOWORD(wParam), lfs);
-#if 0
-    case WM_CTLCOLOR:
-         SetBkColor((HDC16)wParam, 0x00C0C0C0);
-         switch (HIWORD(lParam))
-         {
-        case CTLCOLOR_BTN:
-            SetTextColor((HDC16)wParam, 0x00000000);
-             return hGRAYBrush;
-       case CTLCOLOR_STATIC:
-             SetTextColor((HDC16)wParam, 0x00000000);
-             return hGRAYBrush;
-       }
-      break;
-#endif
-    }
-    return FALSE;
-}
-
-
-/***********************************************************************
- *           GetFileName31A                                 [internal]
- *
- * Creates a win31 style dialog box for the user to select a file to open/save.
- */
-static BOOL GetFileName31A(LPOPENFILENAMEA lpofn, /* address of structure with data*/
-                           UINT dlgType /* type dialogue : open/save */
-                           )
-{
-    BOOL bRet = FALSE;
-    PFD31_DATA lfs;
-
-    if (!lpofn || !FD31_Init()) return FALSE;
-
-    TRACE("ofn flags %08x\n", lpofn->Flags);
-    lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, FALSE);
-    if (lfs)
-    {
-        bRet = DialogBoxIndirectParamA( COMDLG32_hInstance, lfs->template, lpofn->hwndOwner,
-                                        FD32_FileOpenDlgProc, (LPARAM)lfs);
-        FD31_DestroyPrivate(lfs);
-    }
-
-    TRACE("return lpstrFile='%s' !\n", lpofn->lpstrFile);
-    return bRet;
-}
-
-/***********************************************************************
- *           GetFileName31W                                 [internal]
- *
- * Creates a win31 style dialog box for the user to select a file to open/save
- */
-static BOOL GetFileName31W(LPOPENFILENAMEW lpofn, /* address of structure with data*/
-                           UINT dlgType /* type dialogue : open/save */
-                           )
-{
-    BOOL bRet = FALSE;
-    PFD31_DATA lfs;
-
-    if (!lpofn || !FD31_Init()) return FALSE;
-
-    lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, TRUE);
-    if (lfs)
-    {
-        bRet = DialogBoxIndirectParamW( COMDLG32_hInstance, lfs->template, lpofn->hwndOwner,
-                                        FD32_FileOpenDlgProc, (LPARAM)lfs);
-        FD31_DestroyPrivate(lfs);
-    }
-
-    TRACE("file %s, file offset %d, ext offset %d\n",
-          debugstr_w(lpofn->lpstrFile), lpofn->nFileOffset, lpofn->nFileExtension);
-    return bRet;
+    return (flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE) &&
+            !(flags & OFN_EXPLORER));
 }
 
 /* ------------------ APIs ---------------------- */
@@ -4194,24 +4012,29 @@ static BOOL GetFileName31W(LPOPENFILENAMEW lpofn, /* address of structure with d
  *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
  *
  */
-BOOL WINAPI GetOpenFileNameA(
-       LPOPENFILENAMEA ofn) /* [in/out] address of init structure */
+BOOL WINAPI GetOpenFileNameA(OPENFILENAMEA *ofn)
 {
-    BOOL win16look = FALSE;
+    TRACE("flags 0x%08x\n", ofn->Flags);
 
-    TRACE("flags %08x\n", ofn->Flags);
+    if (!valid_struct_size( ofn->lStructSize ))
+    {
+        COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE );
+        return FALSE;
+    }
 
     /* OFN_FILEMUSTEXIST implies OFN_PATHMUSTEXIST */
     if (ofn->Flags & OFN_FILEMUSTEXIST)
         ofn->Flags |= OFN_PATHMUSTEXIST;
 
-    if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
-        win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE;
-
-    if (win16look)
+    if (is_win16_looks(ofn->Flags))
         return GetFileName31A(ofn, OPEN_DIALOG);
     else
-        return GetFileDialog95A(ofn, OPEN_DIALOG);
+    {
+        FileOpenDlgInfos info;
+
+        init_filedlg_infoA(ofn, &info);
+        return GetFileDialog95(&info, OPEN_DIALOG);
+    }
 }
 
 /***********************************************************************
@@ -4224,24 +4047,29 @@ BOOL WINAPI GetOpenFileNameA(
  *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
  *
  */
-BOOL WINAPI GetOpenFileNameW(
-       LPOPENFILENAMEW ofn) /* [in/out] address of init structure */
+BOOL WINAPI GetOpenFileNameW(OPENFILENAMEW *ofn)
 {
-    BOOL win16look = FALSE;
+    TRACE("flags 0x%08x\n", ofn->Flags);
 
-    TRACE("flags %08x\n", ofn->Flags);
+    if (!valid_struct_size( ofn->lStructSize ))
+    {
+        COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE );
+        return FALSE;
+    }
 
     /* OFN_FILEMUSTEXIST implies OFN_PATHMUSTEXIST */
     if (ofn->Flags & OFN_FILEMUSTEXIST)
         ofn->Flags |= OFN_PATHMUSTEXIST;
 
-    if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
-        win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE;
-
-    if (win16look)
+    if (is_win16_looks(ofn->Flags))
         return GetFileName31W(ofn, OPEN_DIALOG);
     else
-        return GetFileDialog95W(ofn, OPEN_DIALOG);
+    {
+        FileOpenDlgInfos info;
+
+        init_filedlg_infoW(ofn, &info);
+        return GetFileDialog95(&info, OPEN_DIALOG);
+    }
 }
 
 
@@ -4255,18 +4083,23 @@ BOOL WINAPI GetOpenFileNameW(
  *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
  *
  */
-BOOL WINAPI GetSaveFileNameA(
-       LPOPENFILENAMEA ofn) /* [in/out] address of init structure */
+BOOL WINAPI GetSaveFileNameA(OPENFILENAMEA *ofn)
 {
-    BOOL win16look = FALSE;
-
-    if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
-        win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE;
+    if (!valid_struct_size( ofn->lStructSize ))
+    {
+        COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE );
+        return FALSE;
+    }
 
-    if (win16look)
+    if (is_win16_looks(ofn->Flags))
         return GetFileName31A(ofn, SAVE_DIALOG);
     else
-        return GetFileDialog95A(ofn, SAVE_DIALOG);
+    {
+        FileOpenDlgInfos info;
+
+        init_filedlg_infoA(ofn, &info);
+        return GetFileDialog95(&info, SAVE_DIALOG);
+    }
 }
 
 /***********************************************************************
@@ -4282,15 +4115,21 @@ BOOL WINAPI GetSaveFileNameA(
 BOOL WINAPI GetSaveFileNameW(
        LPOPENFILENAMEW ofn) /* [in/out] address of init structure */
 {
-    BOOL win16look = FALSE;
-
-    if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
-        win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE;
+    if (!valid_struct_size( ofn->lStructSize ))
+    {
+        COMDLG32_SetCommDlgExtendedError( CDERR_STRUCTSIZE );
+        return FALSE;
+    }
 
-    if (win16look)
+    if (is_win16_looks(ofn->Flags))
         return GetFileName31W(ofn, SAVE_DIALOG);
     else
-        return GetFileDialog95W(ofn, SAVE_DIALOG);
+    {
+        FileOpenDlgInfos info;
+
+        init_filedlg_infoW(ofn, &info);
+        return GetFileDialog95(&info, SAVE_DIALOG);
+    }
 }
 
 /***********************************************************************