/*
 * COMMDLG - File Dialogs
 *
 * Copyright 1994 Martin Ayotte
 * Copyright 1996 Albrecht Kleine
 */
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "wine/winbase16.h"
#include "wine/winuser16.h"
#include "ldt.h"
#include "heap.h"
#include "commdlg.h"
#include "dialog.h"
#include "dlgs.h"
#include "module.h"
#include "drive.h"
#include "debugtools.h"
#include "winproc.h"
#include "cderr.h"
#include "tweak.h"

DEFAULT_DEBUG_CHANNEL(commdlg);

#include "cdlg.h"

static HICON16 hFolder = 0;
static HICON16 hFolder2 = 0;
static HICON16 hFloppy = 0;
static HICON16 hHDisk = 0;
static HICON16 hCDRom = 0;
static HICON16 hNet = 0;
static int fldrHeight = 0;
static int fldrWidth = 0;

static const char defaultfilter[]=" \0\0";
#define OFN_PROP "FILEDLG_OFN_LPARAM"

/***********************************************************************
 *
 * Windows 3.1 OpenFileName/SaveFileName dialog
 *
 */

LRESULT WINAPI FileOpenDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
				 LPARAM lParam);
LRESULT WINAPI FileSaveDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
				 LPARAM lParam);

/***********************************************************************
 * 				FileDlg_Init			[internal]
 */
static BOOL FileDlg_Init(void)
{
    static BOOL initialized = 0;
    CURSORICONINFO *fldrInfo;
    
    if (!initialized) {
	if (!hFolder) hFolder = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FOLDER));
	if (!hFolder2) hFolder2 = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FOLDER2));
	if (!hFloppy) hFloppy = LoadIcon16(0, MAKEINTRESOURCE16(OIC_FLOPPY));
	if (!hHDisk) hHDisk = LoadIcon16(0, MAKEINTRESOURCE16(OIC_HDISK));
	if (!hCDRom) hCDRom = LoadIcon16(0, MAKEINTRESOURCE16(OIC_CDROM));
	if (!hNet) hNet = LoadIcon16(0, MAKEINTRESOURCE16(OIC_NETWORK));
	if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 || 
	    hHDisk == 0 || hCDRom == 0 || hNet == 0)
	{
	    ERR("Error loading icons !\n");
	    return FALSE;
	}
	fldrInfo = (CURSORICONINFO *) GlobalLock16( hFolder2 );
	if (!fldrInfo)
	{	
	    ERR("Error measuring icons !\n");
	    return FALSE;
	}
	fldrHeight = fldrInfo -> nHeight;
	fldrWidth = fldrInfo -> nWidth;
	GlobalUnlock16( hFolder2 );
	initialized = TRUE;
    }
    return TRUE;
}

/***********************************************************************
 *           FileOpenDlgProc [internal]
 *
 * FIXME: Convert to real 32-bit message processing
 */
static LRESULT WINAPI FileOpenDlgProc(HWND hDlg, UINT msg,
                                      WPARAM wParam, LPARAM lParam)
{
    UINT16 msg16;
    MSGPARAM16 mp16;

    mp16.lParam = lParam;
    if (WINPROC_MapMsg32ATo16( hDlg, msg, wParam,
                               &msg16, &mp16.wParam, &mp16.lParam ) == -1)
        return 0;
    mp16.lResult = FileOpenDlgProc16( (HWND16)hDlg, msg16, 
                                      mp16.wParam, mp16.lParam );
    
    WINPROC_UnmapMsg32ATo16( hDlg, msg, wParam, lParam, &mp16 );
    return mp16.lResult;
}

/***********************************************************************
 *           FileSaveDlgProc [internal]
 *
 * FIXME: Convert to real 32-bit message processing
 */
static LRESULT WINAPI FileSaveDlgProc(HWND hDlg, UINT msg,
                                      WPARAM wParam, LPARAM lParam)
{
    UINT16 msg16;
    MSGPARAM16 mp16;

    mp16.lParam = lParam;
    if (WINPROC_MapMsg32ATo16( hDlg, msg, wParam,
                               &msg16, &mp16.wParam, &mp16.lParam ) == -1)
        return 0;
    mp16.lResult = FileSaveDlgProc16( (HWND16)hDlg, msg16, 
                                      mp16.wParam, mp16.lParam );
    
    WINPROC_UnmapMsg32ATo16( hDlg, msg, wParam, lParam, &mp16 );
    return mp16.lResult;
}

/***********************************************************************
 *           GetOpenFileName16   (COMMDLG.1)
 *
 * Creates a dialog box for the user to select a file to open.
 *
 * RETURNS
 *    TRUE on success: user selected a valid file
 *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
 *
 * BUGS
 *    unknown, there are some FIXME's left.
 */
BOOL16 WINAPI GetOpenFileName16( 
				SEGPTR ofn /* addess of structure with data*/
				)
{
    HINSTANCE hInst;
    HANDLE hDlgTmpl = 0, hResInfo;
    BOOL bRet = FALSE, win32Format = FALSE;
    HWND hwndDialog;
    LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
    LPCVOID template;
    char defaultopen[]="Open File";
    char *str=0,*str1=0;

    if (!lpofn || !FileDlg_Init()) return FALSE;

    if (lpofn->Flags & OFN_WINE) {
	    if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
	    {
		if (!(template = LockResource( MapHModuleSL(lpofn->hInstance ))))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
		    return FALSE;
		}
	    }
	    else if (lpofn->Flags & OFN_ENABLETEMPLATE)
	    {
		if (!(hResInfo = FindResourceA(MapHModuleSL(lpofn->hInstance),
						PTR_SEG_TO_LIN(lpofn->lpTemplateName), RT_DIALOGA)))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
		    return FALSE;
		}
		if (!(hDlgTmpl = LoadResource( MapHModuleSL(lpofn->hInstance),
						 hResInfo )) ||
		    !(template = LockResource( hDlgTmpl )))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
		    return FALSE;
		}
	    } else {
		if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "OPEN_FILE", RT_DIALOGA)))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
		    return FALSE;
		}
		if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
		    !(template = LockResource( hDlgTmpl )))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
		    return FALSE;
		}
	    }
	    win32Format = TRUE;
    } else {
	    if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
	    {
		if (!(template = LockResource16( lpofn->hInstance )))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
		    return FALSE;
		}
	    }
	    else if (lpofn->Flags & OFN_ENABLETEMPLATE)
	    {
		if (!(hResInfo = FindResource16(lpofn->hInstance,
						lpofn->lpTemplateName,
                                                RT_DIALOG16)))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
		    return FALSE;
		}
		if (!(hDlgTmpl = LoadResource16( lpofn->hInstance, hResInfo )) ||
		    !(template = LockResource16( hDlgTmpl )))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
		    return FALSE;
		}
	    } else {
		if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "OPEN_FILE", RT_DIALOGA)))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
		    return FALSE;
		}
		if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
		    !(template = LockResource( hDlgTmpl )))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
		    return FALSE;
		}
		win32Format = TRUE;
	    }
    }

    hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );

    if (!(lpofn->lpstrFilter))
      {
       str = SEGPTR_ALLOC(sizeof(defaultfilter));
       TRACE("Alloc %p default for Filetype in GetOpenFileName\n",str);
       memcpy(str,defaultfilter,sizeof(defaultfilter));
       lpofn->lpstrFilter=SEGPTR_GET(str);
      }

    if (!(lpofn->lpstrTitle))
      {
       str1 = SEGPTR_ALLOC(strlen(defaultopen)+1);
       TRACE("Alloc %p default for Title in GetOpenFileName\n",str1);
       strcpy(str1,defaultopen);
       lpofn->lpstrTitle=SEGPTR_GET(str1);
      }

    /* FIXME: doesn't handle win32 format correctly yet */
    hwndDialog = DIALOG_CreateIndirect( hInst, template, win32Format,
                                        lpofn->hwndOwner,
                                        (DLGPROC16)FileOpenDlgProc,
                                        ofn, WIN_PROC_32A );
    if (hwndDialog) bRet = DIALOG_DoDialogBox( hwndDialog, lpofn->hwndOwner );

    if (str1)
      {
       TRACE("Freeing %p default for Title in GetOpenFileName\n",str1);
        SEGPTR_FREE(str1);
       lpofn->lpstrTitle=0;
      }

    if (str)
      {
       TRACE("Freeing %p default for Filetype in GetOpenFileName\n",str);
        SEGPTR_FREE(str);
       lpofn->lpstrFilter=0;
      }

    if (hDlgTmpl) {
	    if (lpofn->Flags & OFN_WINE)
		    FreeResource( hDlgTmpl );
	    else
		    FreeResource16( hDlgTmpl );
    }

    TRACE("return lpstrFile='%s' !\n", 
           (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
    return bRet;
}


/***********************************************************************
 *           GetSaveFileName   (COMMDLG.2)
 *
 * Creates a dialog box for the user to select a file to save.
 *
 * RETURNS
 *    TRUE on succes: user enters a valid file
 *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
 *
 * BUGS
 *    unknown. There are some FIXME's left.
 */
BOOL16 WINAPI GetSaveFileName16( 
				SEGPTR ofn /* addess of structure with data*/
				)
{
    HINSTANCE hInst;
    HANDLE hDlgTmpl = 0;
    BOOL bRet = FALSE, win32Format = FALSE;
    LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
    LPCVOID template;
    HWND hwndDialog;
    char defaultsave[]="Save as";
    char *str =0,*str1=0;

    if (!lpofn || !FileDlg_Init()) return FALSE;

    if (lpofn->Flags & OFN_WINE) {
	    if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
	    {
		if (!(template = LockResource( MapHModuleSL(lpofn->hInstance ))))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
		    return FALSE;
		}
	    }
	    else if (lpofn->Flags & OFN_ENABLETEMPLATE)
	    {
		HANDLE hResInfo;
		if (!(hResInfo = FindResourceA(MapHModuleSL(lpofn->hInstance),
						 PTR_SEG_TO_LIN(lpofn->lpTemplateName),
                                                 RT_DIALOGA)))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
		    return FALSE;
		}
		if (!(hDlgTmpl = LoadResource(MapHModuleSL(lpofn->hInstance),
						hResInfo)) ||
		    !(template = LockResource(hDlgTmpl)))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
		    return FALSE;
		}
		win32Format= TRUE;
	    } else {
		HANDLE hResInfo;
		if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "SAVE_FILE", RT_DIALOGA)))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
		    return FALSE;
		}
		if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
		    !(template = LockResource( hDlgTmpl )))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
		    return FALSE;
		}
		win32Format = TRUE;
	    }
    } else {
	    if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
	    {
		if (!(template = LockResource16( lpofn->hInstance )))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
		    return FALSE;
		}
	    }
	    else if (lpofn->Flags & OFN_ENABLETEMPLATE)
	    {
		HANDLE16 hResInfo;
		if (!(hResInfo = FindResource16(lpofn->hInstance,
						lpofn->lpTemplateName,
                                                RT_DIALOG16)))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
		    return FALSE;
		}
		if (!(hDlgTmpl = LoadResource16( lpofn->hInstance, hResInfo )) ||
		    !(template = LockResource16( hDlgTmpl )))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
		    return FALSE;
		}
	} else {
		HANDLE hResInfo;
		if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "SAVE_FILE", RT_DIALOGA)))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
		    return FALSE;
		}
		if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
		    !(template = LockResource( hDlgTmpl )))
		{
		    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
		    return FALSE;
		}
		win32Format = TRUE;
	}
    }

    hInst = GetWindowLongA( lpofn->hwndOwner, GWL_HINSTANCE );

    if (!(lpofn->lpstrFilter))
      {
       str = SEGPTR_ALLOC(sizeof(defaultfilter));
       TRACE("Alloc default for Filetype in GetSaveFileName\n");
       memcpy(str,defaultfilter,sizeof(defaultfilter));
       lpofn->lpstrFilter=SEGPTR_GET(str);
      }

    if (!(lpofn->lpstrTitle))
      {
       str1 = SEGPTR_ALLOC(sizeof(defaultsave)+1);
       TRACE("Alloc default for Title in GetSaveFileName\n");
       strcpy(str1,defaultsave);
       lpofn->lpstrTitle=SEGPTR_GET(str1);
      }

    hwndDialog = DIALOG_CreateIndirect( hInst, template, win32Format,
                                        lpofn->hwndOwner,
                                        (DLGPROC16)FileSaveDlgProc,
                                        ofn, WIN_PROC_32A );
    if (hwndDialog) bRet = DIALOG_DoDialogBox( hwndDialog, lpofn->hwndOwner );

    if (str1)
      {
       TRACE("Freeing %p default for Title in GetSaveFileName\n",str1);
        SEGPTR_FREE(str1);
       lpofn->lpstrTitle=0;
      }
 
    if (str)
      {
       TRACE("Freeing %p default for Filetype in GetSaveFileName\n",str);
        SEGPTR_FREE(str);
       lpofn->lpstrFilter=0;
      }
    
    if (hDlgTmpl) {
	    if (lpofn->Flags & OFN_WINE)
		    FreeResource( hDlgTmpl );
	    else
		    FreeResource16( hDlgTmpl );
    }

    TRACE("return lpstrFile='%s' !\n", 
            (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
    return bRet;
}

/***********************************************************************
 *                              FILEDLG_StripEditControl        [internal]
 * Strip pathnames off the contents of the edit control.
 */
static void FILEDLG_StripEditControl(HWND16 hwnd)
{
    char temp[512], *cp;

    GetDlgItemTextA( hwnd, edt1, temp, sizeof(temp) );
    cp = strrchr(temp, '\\');
    if (cp != NULL) {
	strcpy(temp, cp+1);
    }
    cp = strrchr(temp, ':');
    if (cp != NULL) {
	strcpy(temp, cp+1);
    }
    /* FIXME: shouldn't we do something with the result here? ;-) */
}

/***********************************************************************
 * 				FILEDLG_ScanDir			[internal]
 */
static BOOL FILEDLG_ScanDir(HWND16 hWnd, LPSTR newPath)
{
    char 		buffer[512];
	 char*  		str = buffer;
    int 			drive;
    HWND 		hlb;

    lstrcpynA(buffer, newPath, sizeof(buffer));

    if (str[0] && (str[1] == ':')) {
        drive = toupper(str[0]) - 'A';
        str += 2;
        if (!DRIVE_SetCurrentDrive(drive)) 
			  return FALSE;
    } else {
		 drive = DRIVE_GetCurrentDrive();
	 }

    if (str[0] && !DRIVE_Chdir(drive, str)) {
		 return FALSE;
    }

    GetDlgItemTextA(hWnd, edt1, buffer, sizeof(buffer));
    if ((hlb = GetDlgItem(hWnd, lst1)) != 0) {
		 char*	scptr; /* ptr on semi-colon */
		 char*	filter = buffer;

		 TRACE("Using filter %s\n", filter);
		 SendMessageA(hlb, LB_RESETCONTENT, 0, 0);
		 while (filter) {
			 scptr = strchr(filter, ';');
			 if (scptr)	*scptr = 0;
			 TRACE("Using file spec %s\n", filter);
			 if (SendMessageA(hlb, LB_DIR, 0, (LPARAM)filter) == LB_ERR)
				 return FALSE;
			 if (scptr) *scptr = ';';
			 filter = (scptr) ? (scptr + 1) : 0;
		 }
	 }

    strcpy(buffer, "*.*");
    return DlgDirListA(hWnd, buffer, lst2, stc1, DDL_EXCLUSIVE | DDL_DIRECTORY);
}

/***********************************************************************
 * 				FILEDLG_GetFileType		[internal]
 */

static LPSTR FILEDLG_GetFileType(LPSTR cfptr, LPSTR fptr, WORD index)
{
  int n, i;
  i = 0;
  if (cfptr)
    for ( ;(n = strlen(cfptr)) != 0; i++) 
      {
	cfptr += n + 1;
	if (i == index)
	  return cfptr;
	cfptr += strlen(cfptr) + 1;
      }
  if (fptr)
    for ( ;(n = strlen(fptr)) != 0; i++) 
      {
	fptr += n + 1;
	if (i == index)
	  return fptr;
	fptr += strlen(fptr) + 1;
    }
  return "*.*"; /* FIXME */
}

/***********************************************************************
 *                              FILEDLG_WMDrawItem              [internal]
 */
static LONG FILEDLG_WMDrawItem(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam,int savedlg)
{
    LPDRAWITEMSTRUCT16 lpdis = (LPDRAWITEMSTRUCT16)PTR_SEG_TO_LIN(lParam);
    char *str;
    HICON16 hIcon;
    COLORREF oldText = 0, oldBk = 0;

    if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1)
    {
        if (!(str = SEGPTR_ALLOC(512))) return FALSE;
	SendMessage16(lpdis->hwndItem, LB_GETTEXT16, lpdis->itemID, 
                      (LPARAM)SEGPTR_GET(str));

	if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
	{
	    oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
	    oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
	}
	if (savedlg)
	    SetTextColor(lpdis->hDC,GetSysColor(COLOR_GRAYTEXT) );

	ExtTextOut16(lpdis->hDC, lpdis->rcItem.left + 1,
                  lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
                  &(lpdis->rcItem), str, strlen(str), NULL);

	if (lpdis->itemState & ODS_SELECTED)
	    DrawFocusRect16( lpdis->hDC, &(lpdis->rcItem) );

	if ((lpdis->itemState & ODS_SELECTED) && !savedlg)
	{
	    SetBkColor( lpdis->hDC, oldBk );
	    SetTextColor( lpdis->hDC, oldText );
	}
        SEGPTR_FREE(str);
	return TRUE;
    }

    if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2)
    {
        if (!(str = SEGPTR_ALLOC(512))) return FALSE;
	SendMessage16(lpdis->hwndItem, LB_GETTEXT16, lpdis->itemID, 
                      (LPARAM)SEGPTR_GET(str));

	if (lpdis->itemState & ODS_SELECTED)
	{
	    oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
	    oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
	}
	ExtTextOut16(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
                  lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
                  &(lpdis->rcItem), str, strlen(str), NULL);

	if (lpdis->itemState & ODS_SELECTED)
	    DrawFocusRect16( lpdis->hDC, &(lpdis->rcItem) );

	if (lpdis->itemState & ODS_SELECTED)
	{
	    SetBkColor( lpdis->hDC, oldBk );
	    SetTextColor( lpdis->hDC, oldText );
	}
	DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hFolder);
        SEGPTR_FREE(str);
	return TRUE;
    }
    if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2)
    {
        if (!(str = SEGPTR_ALLOC(512))) return FALSE;
	SendMessage16(lpdis->hwndItem, CB_GETLBTEXT16, lpdis->itemID, 
                      (LPARAM)SEGPTR_GET(str));
        switch(DRIVE_GetType( str[2] - 'a' ))
        {
        case TYPE_FLOPPY:  hIcon = hFloppy; break;
        case TYPE_CDROM:   hIcon = hCDRom; break;
        case TYPE_NETWORK: hIcon = hNet; break;
        case TYPE_HD:
        default:           hIcon = hHDisk; break;
        }
	if (lpdis->itemState & ODS_SELECTED)
	{
	    oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
	    oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
	}
	ExtTextOut16(lpdis->hDC, lpdis->rcItem.left + fldrWidth,
                  lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED,
                  &(lpdis->rcItem), str, strlen(str), NULL);

	if (lpdis->itemState & ODS_SELECTED)
	{
	    SetBkColor( lpdis->hDC, oldBk );
	    SetTextColor( lpdis->hDC, oldText );
	}
	DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hIcon);
        SEGPTR_FREE(str);
	return TRUE;
    }
    return FALSE;
}

/***********************************************************************
 *                              FILEDLG_WMMeasureItem           [internal]
 */
static LONG FILEDLG_WMMeasureItem(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam) 
{
    LPMEASUREITEMSTRUCT16 lpmeasure;
    
    lpmeasure = (LPMEASUREITEMSTRUCT16)PTR_SEG_TO_LIN(lParam);
    lpmeasure->itemHeight = fldrHeight;
    return TRUE;
}

/***********************************************************************
 *                              FILEDLG_HookCallChk             [internal]
 */
static int FILEDLG_HookCallChk(LPOPENFILENAME16 lpofn)
{
 if (lpofn)
  if (lpofn->Flags & OFN_ENABLEHOOK)
   if (lpofn->lpfnHook)
    return 1;
 return 0;   
} 

/***********************************************************************
 *                              FILEDLG_CallWindowProc             [internal]
 *
 * Adapt the structures back for win32 calls so the callee can read lpCustData
 */
static BOOL FILEDLG_CallWindowProc(LPOPENFILENAME16 lpofn,HWND hwnd,
	UINT wMsg,WPARAM wParam,LPARAM lParam

) {
	BOOL	        needstruct;
        BOOL          result = FALSE;
        WINDOWPROCTYPE  ProcType;               /* Type of Hook Function to be called. */

        /* TRUE if lParam points to the OPENFILENAME16 Structure */
	needstruct = (PTR_SEG_TO_LIN(lParam) == lpofn);

        ProcType   = (lpofn->Flags & OFN_WINE)
                     ? (lpofn->Flags & OFN_UNICODE)             /* 32-Bit call to GetOpenFileName */
                       ? WIN_PROC_32W : WIN_PROC_32A
                     : WIN_PROC_16;                             /* 16-Bit call to GetOpenFileName */

	if (!(lpofn->Flags & OFN_WINE))
                /* Call to 16-Bit Hooking function... No Problem at all. */
		return (BOOL)CallWindowProc16(
			(WNDPROC16)lpofn->lpfnHook,hwnd,(UINT16)wMsg,(WPARAM16)wParam,lParam
		);
	/* |OFN_WINE32 */
        if (needstruct)
        {
           /* Parameter lParam points to lpofn... Convert Structure Data... */
       	   if (lpofn->Flags & OFN_UNICODE)
           {
                OPENFILENAMEW ofnw;

                /* FIXME: probably needs more converted */
                ofnw.lCustData = lpofn->lCustData;
                return (BOOL)CallWindowProcW(
                         (WNDPROC)lpofn->lpfnHook,hwnd,wMsg,wParam,(LPARAM)&ofnw
                );
           }
           else /* ! |OFN_UNICODE */
           {
		OPENFILENAMEA ofna;

		/* FIXME: probably needs more converted */
		ofna.lCustData = lpofn->lCustData;
		return (BOOL)CallWindowProcA(
		        (WNDPROC)lpofn->lpfnHook,hwnd,wMsg,wParam,(LPARAM)&ofna
		);
           }
	}
        else /* ! needstruct */
        {
                HWINDOWPROC     hWindowProc=NULL;

                if (WINPROC_SetProc(&hWindowProc, (WNDPROC16)lpofn->lpfnHook, ProcType, WIN_PROC_WINDOW))
                {
                    /* Call Window Procedure converting 16-Bit Type Parameters to 32-Bit Type Parameters */
                    result = CallWindowProc16( (WNDPROC16)hWindowProc,
                                                      hwnd, wMsg, wParam, lParam );

                    result = LOWORD(result);

                    WINPROC_FreeProc( hWindowProc, WIN_PROC_WINDOW );
                }

                return result;

        }
}


/***********************************************************************
 *                              FILEDLG_WMInitDialog            [internal]
 */

static LONG FILEDLG_WMInitDialog(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam) 
{
  int i, n;
  LPOPENFILENAME16 lpofn;
  char tmpstr[512];
  LPSTR pstr, old_pstr;
  SetPropA(hWnd,OFN_PROP,lParam);
  lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(lParam);
  if (lpofn->lpstrTitle) SetWindowText16( hWnd, lpofn->lpstrTitle );
  /* read custom filter information */
  if (lpofn->lpstrCustomFilter)
    {
      pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter);
      n = 0;
      TRACE("lpstrCustomFilter = %p\n", pstr);
      while(*pstr)
	{
	  old_pstr = pstr;
          i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING16, 0,
                                   (LPARAM)lpofn->lpstrCustomFilter + n );
          n += strlen(pstr) + 1;
	  pstr += strlen(pstr) + 1;
	  TRACE("add str='%s' "
			  "associated to '%s'\n", old_pstr, pstr);
          SendDlgItemMessage16(hWnd, cmb1, CB_SETITEMDATA16, i, (LPARAM)pstr);
          n += strlen(pstr) + 1;
	  pstr += strlen(pstr) + 1;
	}
    }
  /* read filter information */
  if (lpofn->lpstrFilter) {
	pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFilter);
	n = 0;
	while(*pstr) {
	  old_pstr = pstr;
	  i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING16, 0,
				       (LPARAM)lpofn->lpstrFilter + n );
	  n += strlen(pstr) + 1;
	  pstr += strlen(pstr) + 1;
	  TRACE("add str='%s' "
			  "associated to '%s'\n", old_pstr, pstr);
	  SendDlgItemMessage16(hWnd, cmb1, CB_SETITEMDATA16, i, (LPARAM)pstr);
	  n += strlen(pstr) + 1;
	  pstr += strlen(pstr) + 1;
	}
  }
  /* set default filter */
  if (lpofn->nFilterIndex == 0 && lpofn->lpstrCustomFilter == (SEGPTR)NULL)
  	lpofn->nFilterIndex = 1;
  SendDlgItemMessage16(hWnd, cmb1, CB_SETCURSEL16, lpofn->nFilterIndex - 1, 0);    
  lstrcpynA(tmpstr, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
	     PTR_SEG_TO_LIN(lpofn->lpstrFilter), lpofn->nFilterIndex - 1),512);
  TRACE("nFilterIndex = %ld, SetText of edt1 to '%s'\n", 
  			lpofn->nFilterIndex, tmpstr);
  SetDlgItemTextA( hWnd, edt1, tmpstr );
  /* get drive list */
  *tmpstr = 0;
  DlgDirListComboBoxA(hWnd, tmpstr, cmb2, 0, DDL_DRIVES | DDL_EXCLUSIVE);
  /* read initial directory */
  if (PTR_SEG_TO_LIN(lpofn->lpstrInitialDir) != NULL) 
    {
      int len;
      lstrcpynA(tmpstr, PTR_SEG_TO_LIN(lpofn->lpstrInitialDir), 511);
      len=strlen(tmpstr);
      if (len > 0 && tmpstr[len-1] != '\\'  && tmpstr[len-1] != ':') {
        tmpstr[len]='\\';
        tmpstr[len+1]='\0';
      }
    }
  else
    *tmpstr = 0;
  if (!FILEDLG_ScanDir(hWnd, tmpstr)) {
    *tmpstr = 0;
    if (!FILEDLG_ScanDir(hWnd, tmpstr))
      WARN("Couldn't read initial directory %s!\n",tmpstr);
  }
  /* select current drive in combo 2, omit missing drives */
  for(i=0, n=-1; i<=DRIVE_GetCurrentDrive(); i++)
    if (DRIVE_IsValid(i))                  n++;
  SendDlgItemMessage16(hWnd, cmb2, CB_SETCURSEL16, n, 0);
  if (!(lpofn->Flags & OFN_SHOWHELP))
    ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
  if (lpofn->Flags & OFN_HIDEREADONLY)
    ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE); 
  if (FILEDLG_HookCallChk(lpofn))
     return (BOOL16)FILEDLG_CallWindowProc(lpofn,hWnd,WM_INITDIALOG,wParam,lParam );
  else  
     return TRUE;
}

/***********************************************************************
 *                              FILEDLG_WMCommand               [internal]
 */
BOOL in_update=FALSE;

static LRESULT FILEDLG_WMCommand(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam) 
{
  LONG lRet;
  LPOPENFILENAME16 lpofn;
  OPENFILENAME16 ofn2;
  char tmpstr[512], tmpstr2[512];
  LPSTR pstr, pstr2;
  UINT16 control,notification;

  /* Notifications are packaged differently in Win32 */
  control = wParam;
  notification = HIWORD(lParam);
    
  lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(GetPropA(hWnd,OFN_PROP));
  switch (control)
    {
    case lst1: /* file list */
      FILEDLG_StripEditControl(hWnd);
      if (notification == LBN_DBLCLK)
	goto almost_ok;
      lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL16, 0, 0);
      if (lRet == LB_ERR) return TRUE;
      if ((pstr = SEGPTR_ALLOC(512)))
      {
          SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT16, lRet,
                               (LPARAM)SEGPTR_GET(pstr));
          SetDlgItemTextA( hWnd, edt1, pstr );
          SEGPTR_FREE(pstr);
      }
      if (FILEDLG_HookCallChk(lpofn))
       FILEDLG_CallWindowProc(lpofn,hWnd,
                  RegisterWindowMessageA( LBSELCHSTRING ),
                  control, MAKELONG(lRet,CD_LBSELCHANGE));       
      /* FIXME: for OFN_ALLOWMULTISELECT we need CD_LBSELSUB, CD_SELADD, CD_LBSELNOITEMS */                  
      return TRUE;
    case lst2: /* directory list */
      FILEDLG_StripEditControl(hWnd);
      if (notification == LBN_DBLCLK)
	{
	  lRet = SendDlgItemMessage16(hWnd, lst2, LB_GETCURSEL16, 0, 0);
	  if (lRet == LB_ERR) return TRUE;
          pstr = SEGPTR_ALLOC(512);
	  SendDlgItemMessage16(hWnd, lst2, LB_GETTEXT16, lRet,
			     (LPARAM)SEGPTR_GET(pstr));
          strcpy( tmpstr, pstr );
          SEGPTR_FREE(pstr);
	  if (tmpstr[0] == '[')
	    {
	      tmpstr[strlen(tmpstr) - 1] = 0;
	      strcpy(tmpstr,tmpstr+1);
	    }
	  strcat(tmpstr, "\\");
	  goto reset_scan;
	}
      return TRUE;
    case cmb1: /* file type drop list */
      if (notification == CBN_SELCHANGE) 
	{
	  *tmpstr = 0;
	  goto reset_scan;
	}
      return TRUE;
    case chx1:
      return TRUE;
    case pshHelp:
      return TRUE;
    case cmb2: /* disk drop list */
      FILEDLG_StripEditControl(hWnd);
      lRet = SendDlgItemMessage16(hWnd, cmb2, CB_GETCURSEL16, 0, 0L);
      if (lRet == LB_ERR) return 0;
      pstr = SEGPTR_ALLOC(512);
      SendDlgItemMessage16(hWnd, cmb2, CB_GETLBTEXT16, lRet,
                           (LPARAM)SEGPTR_GET(pstr));
      sprintf(tmpstr, "%c:", pstr[2]);
      SEGPTR_FREE(pstr);
      if (notification != CBN_SELCHANGE) return TRUE;
    reset_scan:
      lRet = SendDlgItemMessage16(hWnd, cmb1, CB_GETCURSEL16, 0, 0);
      if (lRet == LB_ERR)
	return TRUE;
      pstr = (LPSTR)SendDlgItemMessage16(hWnd, cmb1, CB_GETITEMDATA16, lRet, 0);
      TRACE("Selected filter : %s\n", pstr);
      SetDlgItemTextA( hWnd, edt1, pstr );
      FILEDLG_ScanDir(hWnd, tmpstr);
      in_update=TRUE;
    case IDOK:
    almost_ok:
      ofn2=*lpofn; /* for later restoring */
      GetDlgItemTextA( hWnd, edt1, tmpstr, sizeof(tmpstr) );
      pstr = strrchr(tmpstr, '\\');
      if (pstr == NULL)
	pstr = strrchr(tmpstr, ':');
      if (strchr(tmpstr,'*') != NULL || strchr(tmpstr,'?') != NULL)
	{
	  /* edit control contains wildcards */
	  if (pstr != NULL)
	    {
	      lstrcpynA(tmpstr2, pstr+1, 512);
	      *(pstr+1) = 0;
	    }
	  else
	    {
	      strcpy(tmpstr2, tmpstr);
	      *tmpstr=0;
	    }
	  TRACE("tmpstr=%s, tmpstr2=%s\n", tmpstr, tmpstr2);
          SetDlgItemTextA( hWnd, edt1, tmpstr2 );
	  FILEDLG_ScanDir(hWnd, tmpstr);
	  return TRUE;
	}
      /* no wildcards, we might have a directory or a filename */
      /* try appending a wildcard and reading the directory */
      pstr2 = tmpstr + strlen(tmpstr);
      if (pstr == NULL || *(pstr+1) != 0)
	strcat(tmpstr, "\\");
      lRet = SendDlgItemMessage16(hWnd, cmb1, CB_GETCURSEL16, 0, 0);
      if (lRet == LB_ERR) return TRUE;
      lpofn->nFilterIndex = lRet + 1;
      TRACE("lpofn->nFilterIndex=%ld\n", lpofn->nFilterIndex);
      lstrcpynA(tmpstr2, 
	     FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
				 PTR_SEG_TO_LIN(lpofn->lpstrFilter),
				 lRet), sizeof(tmpstr2));
      SetDlgItemTextA( hWnd, edt1, tmpstr2 );
      if (!in_update)
      /* if ScanDir succeeds, we have changed the directory */
      if (FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
      /* if not, this must be a filename */
      *pstr2 = 0;
      if (pstr != NULL)
	{
	  /* strip off the pathname */
	  *pstr = 0;
          SetDlgItemTextA( hWnd, edt1, pstr + 1 );
	  lstrcpynA(tmpstr2, pstr+1, sizeof(tmpstr2) );
	  /* Should we MessageBox() if this fails? */
	  if (!FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
	  strcpy(tmpstr, tmpstr2);
	}
      else SetDlgItemTextA( hWnd, edt1, tmpstr );
#if 0
      ShowWindow16(hWnd, SW_HIDE);   /* this should not be necessary ?! (%%%) */
#endif
      {
 	int lenstr2;
	int drive = DRIVE_GetCurrentDrive();
	tmpstr2[0] = 'A'+ drive;
	tmpstr2[1] = ':';
	tmpstr2[2] = '\\';
	lstrcpynA(tmpstr2 + 3, DRIVE_GetDosCwd(drive), 507);
        lenstr2=strlen(tmpstr2);
	if (lenstr2 > 3)
 	   tmpstr2[lenstr2++]='\\';
	lstrcpynA(tmpstr2+lenstr2, tmpstr, 512-lenstr2);
	if (lpofn->lpstrFile)
	  lstrcpynA(PTR_SEG_TO_LIN(lpofn->lpstrFile), tmpstr2,lpofn->nMaxFile);
      }
      lpofn->nFileOffset = strrchr(tmpstr2,'\\') - tmpstr2 +1;
      lpofn->nFileExtension = 0;
      while(tmpstr2[lpofn->nFileExtension] != '.' && tmpstr2[lpofn->nFileExtension] != '\0')
        lpofn->nFileExtension++;
      if (tmpstr2[lpofn->nFileExtension] == '\0')
	lpofn->nFileExtension = 0;
      else
	lpofn->nFileExtension++;

      if(in_update)
       {
         if (FILEDLG_HookCallChk(lpofn))
           FILEDLG_CallWindowProc(lpofn,hWnd,
                                  RegisterWindowMessageA( LBSELCHSTRING ),
                                  control, MAKELONG(lRet,CD_LBSELCHANGE));

         in_update = FALSE;
         return TRUE;
       }
      if (PTR_SEG_TO_LIN(lpofn->lpstrFileTitle) != NULL) 
	{
	  lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL16, 0, 0);
	  SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT16, lRet,
                               lpofn->lpstrFileTitle );
	}
      if (FILEDLG_HookCallChk(lpofn))
      {
       lRet= (BOOL16)FILEDLG_CallWindowProc(lpofn,
               hWnd, RegisterWindowMessageA( FILEOKSTRING ), 0, lParam );
       if (lRet)       
       {
         *lpofn=ofn2; /* restore old state */
#if 0
         ShowWindow16(hWnd, SW_SHOW);               /* only if above (%%%) SW_HIDE used */
#endif         
         break;
       }
      }
      if ((lpofn->Flags & OFN_ALLOWMULTISELECT) && (lpofn->Flags & OFN_EXPLORER)) {
	 if (lpofn->lpstrFile) {
	    LPSTR str = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile);
	    LPSTR ptr = strrchr(str, '\\');
	    str[strlen(str) + 1] = '\0';
	    *ptr = 0;
	 }
      }
      EndDialog(hWnd, TRUE);
      return TRUE;
    case IDCANCEL:
      EndDialog(hWnd, FALSE);
      return TRUE;
    }
  return FALSE;
}

/***********************************************************************
 *           FileOpenDlgProc16   (COMMDLG.6)
 */
LRESULT WINAPI FileOpenDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
                               LPARAM lParam)
{  
 LPOPENFILENAME16 lpofn =(LPOPENFILENAME16)PTR_SEG_TO_LIN(GetPropA(hWnd,OFN_PROP));
 
 if (wMsg!=WM_INITDIALOG)
  if (FILEDLG_HookCallChk(lpofn))
  {
   LRESULT  lRet=(BOOL16)FILEDLG_CallWindowProc(lpofn,hWnd,wMsg,wParam,lParam);
   if (lRet)   
    return lRet;         /* else continue message processing */
  }             
  switch (wMsg)
    {
    case WM_INITDIALOG:
      return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
    case WM_MEASUREITEM:
      return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
    case WM_DRAWITEM:
      return FILEDLG_WMDrawItem(hWnd, wParam, lParam, FALSE);
    case WM_COMMAND:
      return FILEDLG_WMCommand(hWnd, wParam, lParam);
#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;
}

/***********************************************************************
 *           FileSaveDlgProc16   (COMMDLG.7)
 */
LRESULT WINAPI FileSaveDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
                               LPARAM lParam)
{
 LPOPENFILENAME16 lpofn =(LPOPENFILENAME16)PTR_SEG_TO_LIN(GetPropA(hWnd,OFN_PROP));
 
 if (wMsg!=WM_INITDIALOG)
  if (FILEDLG_HookCallChk(lpofn))
  {
   LRESULT  lRet=(BOOL16)FILEDLG_CallWindowProc(lpofn,hWnd,wMsg,wParam,lParam);
   if (lRet)   
    return lRet;         /* else continue message processing */
  }             
  switch (wMsg) {
   case WM_INITDIALOG:
      return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
      
   case WM_MEASUREITEM:
      return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
    
   case WM_DRAWITEM:
      return FILEDLG_WMDrawItem(hWnd, wParam, lParam, TRUE);

   case WM_COMMAND:
      return FILEDLG_WMCommand(hWnd, wParam, lParam);
  }
  
  /*
  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;
   }
   return FALSE;
   
   */
  return FALSE;
}

static BOOL Commdlg_GetFileNameA( BOOL16 (CALLBACK *dofunction)(SEGPTR x),
                                      LPOPENFILENAMEA ofn )
{
	BOOL16 ret;
	LPOPENFILENAME16 ofn16 = SEGPTR_ALLOC(sizeof(OPENFILENAME16));

	memset(ofn16,'\0',sizeof(*ofn16));
	ofn16->lStructSize = sizeof(*ofn16);
	ofn16->hwndOwner = ofn->hwndOwner;
	ofn16->hInstance = MapHModuleLS(ofn->hInstance);
	if (ofn->lpstrFilter) {
		LPSTR	s,x;

		/* filter is a list...  title\0ext\0......\0\0 */
		s = (LPSTR)ofn->lpstrFilter;
		while (*s)
			s = s+strlen(s)+1;
		s++;
		x = (LPSTR)SEGPTR_ALLOC(s-ofn->lpstrFilter);
		memcpy(x,ofn->lpstrFilter,s-ofn->lpstrFilter);
		ofn16->lpstrFilter = SEGPTR_GET(x);
	}
	if (ofn->lpstrCustomFilter) {
		LPSTR	s,x;

		/* filter is a list...  title\0ext\0......\0\0 */
		s = (LPSTR)ofn->lpstrCustomFilter;
		while (*s)
			s = s+strlen(s)+1;
		s++;
		x = SEGPTR_ALLOC(s-ofn->lpstrCustomFilter);
		memcpy(x,ofn->lpstrCustomFilter,s-ofn->lpstrCustomFilter);
		ofn16->lpstrCustomFilter = SEGPTR_GET(x);
	}
	ofn16->nMaxCustFilter = ofn->nMaxCustFilter;
	ofn16->nFilterIndex = ofn->nFilterIndex;
	if (ofn->nMaxFile)
	    ofn16->lpstrFile = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFile));
	ofn16->nMaxFile = ofn->nMaxFile;
	ofn16->nMaxFileTitle = ofn->nMaxFileTitle;
        if (ofn16->nMaxFileTitle)
	    ofn16->lpstrFileTitle = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFileTitle));
	if (ofn->lpstrInitialDir)
	    ofn16->lpstrInitialDir = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpstrInitialDir));
	if (ofn->lpstrTitle)
	    ofn16->lpstrTitle = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpstrTitle));
	ofn16->Flags = ofn->Flags|OFN_WINE;
	ofn16->nFileOffset = ofn->nFileOffset;
	ofn16->nFileExtension = ofn->nFileExtension;
	if (ofn->lpstrDefExt)
	    ofn16->lpstrDefExt = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpstrDefExt));
	ofn16->lCustData = ofn->lCustData;
	ofn16->lpfnHook = (LPOFNHOOKPROC16)ofn->lpfnHook;

	if (ofn->lpTemplateName)
	    ofn16->lpTemplateName = SEGPTR_GET(SEGPTR_STRDUP(ofn->lpTemplateName));

	ret = dofunction(SEGPTR_GET(ofn16));

	ofn->nFileOffset = ofn16->nFileOffset;
	ofn->nFileExtension = ofn16->nFileExtension;
	if (ofn16->lpstrFilter)
	    SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFilter));
	if (ofn16->lpTemplateName)
	    SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpTemplateName));
	if (ofn16->lpstrDefExt)
	    SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrDefExt));
	if (ofn16->lpstrTitle)
	    SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrTitle));
	if (ofn16->lpstrInitialDir)
	    SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrInitialDir));
	if (ofn16->lpstrCustomFilter)
	    SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrCustomFilter));

	if (ofn16->lpstrFile) 
	  {
	    LPCSTR	src = PTR_SEG_TO_LIN(ofn16->lpstrFile);
	    LPSTR	dst = ofn->lpstrFile;

	    if ((ofn->Flags & OFN_ALLOWMULTISELECT) && (ofn->Flags & OFN_EXPLORER)) {
	       /* FIXME(EPP): I tried to use:
		* memcpy(ofn->lpstrFile, PTR_SEG_TO_LIN(ofn16->lpstrFile, ofn->nMaxFile)
		* but it did crash with winamp 2.21, so copy string by string
		*/
	       int	len;
	       do {
		  strcpy(dst, src);
		  len = strlen(dst) + 1;	/* strlen(dst) == strlen(src) */
		  dst += len;
		  src += len;
	       } while (len > 1);
	    } else {
	       strcpy(dst, src);
	    }
	    SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFile));
	  }

	if (ofn16->lpstrFileTitle) 
	  {
	    if (ofn->lpstrFileTitle)
		strcpy(ofn->lpstrFileTitle,
			PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
	    SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
	  }
	SEGPTR_FREE(ofn16);
	return ret;
}

static BOOL Commdlg_GetFileNameW( BOOL16 (CALLBACK *dofunction)(SEGPTR x), 
                                      LPOPENFILENAMEW ofn )
{
	BOOL16 ret;
	LPOPENFILENAME16 ofn16 = SEGPTR_ALLOC(sizeof(OPENFILENAME16));

	memset(ofn16,'\0',sizeof(*ofn16));
	ofn16->lStructSize = sizeof(*ofn16);
	ofn16->hwndOwner = ofn->hwndOwner;
	ofn16->hInstance = MapHModuleLS(ofn->hInstance);
	if (ofn->lpstrFilter) {
		LPWSTR	s;
		LPSTR	x,y;
		int	n;

		/* filter is a list...  title\0ext\0......\0\0 */
		s = (LPWSTR)ofn->lpstrFilter;
		while (*s)
			s = s+lstrlenW(s)+1;
		s++;
		n = s - ofn->lpstrFilter; /* already divides by 2. ptr magic */
		x = y = (LPSTR)SEGPTR_ALLOC(n);
		s = (LPWSTR)ofn->lpstrFilter;
		while (*s) {
			lstrcpyWtoA(x,s);
			x+=lstrlenA(x)+1;
			s+=lstrlenW(s)+1;
		}
		*x=0;
		ofn16->lpstrFilter = SEGPTR_GET(y);
}
	if (ofn->lpstrCustomFilter) {
		LPWSTR	s;
		LPSTR	x,y;
		int	n;

		/* filter is a list...  title\0ext\0......\0\0 */
		s = (LPWSTR)ofn->lpstrCustomFilter;
		while (*s)
			s = s+lstrlenW(s)+1;
		s++;
		n = s - ofn->lpstrCustomFilter;
		x = y = (LPSTR)SEGPTR_ALLOC(n);
		s = (LPWSTR)ofn->lpstrCustomFilter;
		while (*s) {
			lstrcpyWtoA(x,s);
			x+=lstrlenA(x)+1;
			s+=lstrlenW(s)+1;
		}
		*x=0;
		ofn16->lpstrCustomFilter = SEGPTR_GET(y);
	}
	ofn16->nMaxCustFilter = ofn->nMaxCustFilter;
	ofn16->nFilterIndex = ofn->nFilterIndex;
        if (ofn->nMaxFile) 
	   ofn16->lpstrFile = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFile));
	ofn16->nMaxFile = ofn->nMaxFile;
	ofn16->nMaxFileTitle = ofn->nMaxFileTitle;
        if (ofn->nMaxFileTitle)
		ofn16->lpstrFileTitle = SEGPTR_GET(SEGPTR_ALLOC(ofn->nMaxFileTitle));
	if (ofn->lpstrInitialDir)
		ofn16->lpstrInitialDir = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpstrInitialDir));
	if (ofn->lpstrTitle)
		ofn16->lpstrTitle = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpstrTitle));
	ofn16->Flags = ofn->Flags|OFN_WINE|OFN_UNICODE;
	ofn16->nFileOffset = ofn->nFileOffset;
	ofn16->nFileExtension = ofn->nFileExtension;
	if (ofn->lpstrDefExt)
		ofn16->lpstrDefExt = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpstrDefExt));
	ofn16->lCustData = ofn->lCustData;
	ofn16->lpfnHook = (LPOFNHOOKPROC16)ofn->lpfnHook;
	if (ofn->lpTemplateName) 
		ofn16->lpTemplateName = SEGPTR_GET(SEGPTR_STRDUP_WtoA(ofn->lpTemplateName));
	ret = dofunction(SEGPTR_GET(ofn16));

	ofn->nFileOffset = ofn16->nFileOffset;
	ofn->nFileExtension = ofn16->nFileExtension;
	if (ofn16->lpstrFilter)
		SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFilter));
	if (ofn16->lpTemplateName)
		SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpTemplateName));
	if (ofn16->lpstrDefExt)
		SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrDefExt));
	if (ofn16->lpstrTitle)
		SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrTitle));
	if (ofn16->lpstrInitialDir)
		SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrInitialDir));
	if (ofn16->lpstrCustomFilter)
		SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrCustomFilter));

	if (ofn16->lpstrFile)
	  {
	    LPCSTR	src = PTR_SEG_TO_LIN(ofn16->lpstrFile);
	    LPWSTR	dst = ofn->lpstrFile;

	    if ((ofn->Flags & OFN_ALLOWMULTISELECT) && (ofn->Flags & OFN_EXPLORER)) {
	       int	len;
	       do {
		  lstrcpyAtoW(dst, src);
		  dst += lstrlenW(dst) + 1;
		  src += (len = strlen(src) + 1);
	       } while (len > 1);
	    } else {
	       lstrcpyAtoW(ofn->lpstrFile,PTR_SEG_TO_LIN(ofn16->lpstrFile));
	    }
	    SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFile));
	  }

	if (ofn16->lpstrFileTitle) {
	    if (ofn->lpstrFileTitle)
                lstrcpyAtoW(ofn->lpstrFileTitle,
			PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
	    SEGPTR_FREE(PTR_SEG_TO_LIN(ofn16->lpstrFileTitle));
	}
	SEGPTR_FREE(ofn16);
	return ret;
}
/***********************************************************************
 *            GetOpenFileNameA  (COMDLG32.10)
 *
 * Creates a dialog box for the user to select a file to open.
 *
 * RETURNS
 *    TRUE on succes: user enters a valid file
 *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
 *
 */
BOOL WINAPI GetOpenFileNameA(
	LPOPENFILENAMEA ofn) /* address of init structure */
{
    BOOL  newlook;
    
    /* some flags don't allow to match the TWEAK_WineLook */
    if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
    {
      newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
    }
    else
    {
      /* no special flags set, we can match the TWEAK_WineLook */
      newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
    }

    if (newlook)
    {
        return GetFileDialog95A(ofn, OPEN_DIALOG);
    }
    else
    {
       BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetOpenFileName16;
       return Commdlg_GetFileNameA(dofunction,ofn);
    }
}

/***********************************************************************
 *            GetOpenFileNameW (COMDLG32.11)
 *
 * Creates a dialog box for the user to select a file to open.
 *
 * RETURNS
 *    TRUE on succes: user enters a valid file
 *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
 *
 */
BOOL WINAPI GetOpenFileNameW(
	LPOPENFILENAMEW ofn) /* address of init structure */
{
    BOOL  newlook;
    
    /* some flags don't allow to match the TWEAK_WineLook */
    if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
    {
      newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
    }
    else
    {
      /* no special flags set, we can match the TWEAK_WineLook */
      newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
    }

    if (newlook)
    {
        return GetFileDialog95W(ofn, OPEN_DIALOG);
    }
    else
    {
       BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetOpenFileName16;
       return Commdlg_GetFileNameW(dofunction,ofn);
    }
}

/***********************************************************************
 *            GetSaveFileNameA  (COMDLG32.12)
 *
 * Creates a dialog box for the user to select a file to save.
 *
 * RETURNS
 *    TRUE on succes: user enters a valid file
 *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
 *
 */
BOOL WINAPI GetSaveFileNameA(
	LPOPENFILENAMEA ofn) /* address of init structure */
{
    BOOL  newlook;
    
    /* some flags don't allow to match the TWEAK_WineLook */
    if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
    {
      newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
    }
    else
    {
      /* no special flags set, we can match the TWEAK_WineLook */
      newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
    }

    if (newlook)
    {
        return GetFileDialog95A(ofn, SAVE_DIALOG);
    } 
    else
    {
	BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetSaveFileName16;
	return Commdlg_GetFileNameA(dofunction,ofn);
    }
}

/***********************************************************************
 *            GetSaveFileNameW  (COMDLG32.13)
 *
 * Creates a dialog box for the user to select a file to save.
 *
 * RETURNS
 *    TRUE on succes: user enters a valid file
 *    FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
 *
 */
BOOL WINAPI GetSaveFileNameW(
	LPOPENFILENAMEW ofn) /* address of init structure */
{
    BOOL  newlook;
    
    /* some flags don't allow to match the TWEAK_WineLook */
    if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
    {
      newlook = (ofn->Flags & OFN_EXPLORER) ? TRUE : FALSE;
    }
    else
    {
      /* no special flags set, we can match the TWEAK_WineLook */
      newlook = (TWEAK_WineLook>WIN31_LOOK) ? TRUE : FALSE;
    }

    if (newlook)
    {
        return GetFileDialog95W(ofn, SAVE_DIALOG);
    } 
    else
    {
	BOOL16 (CALLBACK * dofunction)(SEGPTR ofn16) = GetSaveFileName16;
	return Commdlg_GetFileNameW(dofunction,ofn);
    }
}
