SHELL32: remove static variables in SHBrowseForFolder implementation

Mike McCormack mike at codeweavers.com
Thu Apr 28 11:16:12 CDT 2005


ChangeLog:
* remove static variables in SHBrowseForFolder implementation
-------------- next part --------------
--- dlls/shell32/brsfolder.c.1	2005-04-28 22:55:59.000000000 +0900
+++ dlls/shell32/brsfolder.c	2005-04-29 01:13:15.000000000 +0900
@@ -37,11 +37,15 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
-static HWND		hwndTreeView;
-static LPBROWSEINFOW	lpBrowseInfo;
-static LPITEMIDLIST	pidlRet;
+typedef struct tagbrowse_info
+{
+    HWND          hWnd;
+    HWND          hwndTreeView;
+    LPBROWSEINFOW lpBrowseInfo;
+    LPITEMIDLIST  pidlRet;
+} browse_info;
 
-typedef struct tagID
+typedef struct tagTV_ITEMDATA
 {
    LPSHELLFOLDER lpsfParent; /* IShellFolder of the parent */
    LPITEMIDLIST  lpi;        /* PIDL relativ to parent */
@@ -49,20 +53,36 @@ typedef struct tagID
    IEnumIDList*  pEnumIL;    /* Children iterator */ 
 } TV_ITEMDATA, *LPTV_ITEMDATA;
 
-static void FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST  lpifq, HTREEITEM hParent, IEnumIDList* lpe);
-static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl, LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM hParent);
-
 #define SUPPORTEDFLAGS (BIF_STATUSTEXT | \
                         BIF_BROWSEFORCOMPUTER | \
                         BIF_RETURNFSANCESTORS | \
                         BIF_RETURNONLYFSDIRS | \
                         BIF_BROWSEINCLUDEFILES)
 
+static void FillTreeView(browse_info*, LPSHELLFOLDER,
+               LPITEMIDLIST, HTREEITEM, IEnumIDList*);
+static HTREEITEM InsertTreeViewItem( browse_info*, IShellFolder *,
+               LPCITEMIDLIST, LPCITEMIDLIST, IEnumIDList*, HTREEITEM);
+
+const WCHAR szBrowseFolderInfo[] = {
+    '_','_','W','I','N','E','_',
+    'B','R','S','F','O','L','D','E','R','D','L','G','_',
+    'I','N','F','O',0
+};
+
 static inline DWORD BrowseFlagsToSHCONTF(UINT ulFlags)
 {
     return SHCONTF_FOLDERS | (ulFlags & BIF_BROWSEINCLUDEFILES ? SHCONTF_NONFOLDERS : 0);
 }
 
+static void browsefolder_callback( LPBROWSEINFOW lpBrowseInfo, HWND hWnd,
+                                   UINT msg, LPARAM param )
+{
+    if (!lpBrowseInfo->lpfn)
+        return;
+    lpBrowseInfo->lpfn( hWnd, BFFM_INITIALIZED, param, lpBrowseInfo->lParam );
+}
+
 /******************************************************************************
  * InitializeTreeView [Internal]
  *
@@ -72,25 +92,23 @@ static inline DWORD BrowseFlagsToSHCONTF
  *  hwndParent [I] The BrowseForFolder dialog
  *  root       [I] ITEMIDLIST of the root shell folder
  */
-static void InitializeTreeView(HWND hwndParent, LPCITEMIDLIST root)
+static void InitializeTreeView( browse_info *info )
 {
     LPITEMIDLIST pidlParent, pidlChild;
     HIMAGELIST hImageList;
     HRESULT hr;
     IShellFolder *lpsfParent, *lpsfRoot;
     IEnumIDList * pEnumChildren = NULL;
+    HTREEITEM item;
+    DWORD flags;
+    LPCITEMIDLIST root = info->lpBrowseInfo->pidlRoot;
 
-    TRACE("dlg=%p tree=%p\n", hwndParent, hwndTreeView );
+    TRACE("%p\n", info );
     
-    hwndTreeView = GetDlgItem (hwndParent, IDD_TREEVIEW);
-    if (!hwndTreeView) {
-        FIXME("Could not get handle to treeview control! Error: %08lx\n", GetLastError());
-        return;
-    }
     Shell_GetImageList(NULL, &hImageList);
 
     if (hImageList)
-        TreeView_SetImageList(hwndTreeView, hImageList, 0);
+        TreeView_SetImageList( info->hwndTreeView, hImageList, 0 );
 
     /* We want to call InsertTreeViewItem down the code, in order to insert
      * the root item of the treeview. Due to InsertTreeViewItem's signature, 
@@ -139,7 +157,8 @@ static void InitializeTreeView(HWND hwnd
         return;
     }
 
-    hr = IShellFolder_EnumObjects(lpsfRoot, hwndParent, BrowseFlagsToSHCONTF(lpBrowseInfo->ulFlags), &pEnumChildren);
+    flags = BrowseFlagsToSHCONTF( info->lpBrowseInfo->ulFlags );
+    hr = IShellFolder_EnumObjects( lpsfRoot, info->hWnd, flags, &pEnumChildren );
     if (!SUCCEEDED(hr)) {
         WARN("Could not get child iterator! hr = %08lx\n", hr);
         IShellFolder_Release(lpsfParent);
@@ -147,8 +166,10 @@ static void InitializeTreeView(HWND hwnd
         return;
     }
 
-    TreeView_DeleteAllItems(hwndTreeView);
-    TreeView_Expand(hwndTreeView, InsertTreeViewItem(lpsfParent, pidlChild, pidlParent, pEnumChildren,  TVI_ROOT), TVE_EXPAND);
+    TreeView_DeleteAllItems( info->hwndTreeView );
+    item = InsertTreeViewItem( info, lpsfParent, pidlChild,
+                               pidlParent, pEnumChildren, TVI_ROOT );
+    TreeView_Expand( info->hwndTreeView, item, TVE_EXPAND );
 
     IShellFolder_Release(lpsfRoot);
     IShellFolder_Release(lpsfParent);
@@ -156,30 +177,32 @@ static void InitializeTreeView(HWND hwnd
 
 static int GetIcon(LPITEMIDLIST lpi, UINT uFlags)
 {
-	SHFILEINFOW    sfi;
-	SHGetFileInfoW((LPCWSTR)lpi, 0 ,&sfi, sizeof(SHFILEINFOW), uFlags);
-	return sfi.iIcon;
+    SHFILEINFOW sfi;
+    SHGetFileInfoW((LPCWSTR)lpi, 0 ,&sfi, sizeof(SHFILEINFOW), uFlags);
+    return sfi.iIcon;
 }
 
 static void GetNormalAndSelectedIcons(LPITEMIDLIST lpifq, LPTVITEMW lpTV_ITEM)
 {
-	LPITEMIDLIST pidlDesktop = NULL;
+    LPITEMIDLIST pidlDesktop = NULL;
+    DWORD flags;
 
-	TRACE("%p %p\n",lpifq, lpTV_ITEM);
+    TRACE("%p %p\n",lpifq, lpTV_ITEM);
 
-	if (!lpifq)
-	{
-	    pidlDesktop = _ILCreateDesktop();
-	    lpifq = pidlDesktop;
-	}
+    if (!lpifq)
+    {
+        pidlDesktop = _ILCreateDesktop();
+        lpifq = pidlDesktop;
+    }
 
-	lpTV_ITEM->iImage = GetIcon(lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
-	lpTV_ITEM->iSelectedImage = GetIcon(lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON);
+    flags = SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON;
+    lpTV_ITEM->iImage = GetIcon( lpifq, flags );
 
-	if (pidlDesktop)
-	    ILFree(pidlDesktop);
+    flags = SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON;
+    lpTV_ITEM->iSelectedImage = GetIcon( lpifq, flags );
 
-	return;
+    if (pidlDesktop)
+        ILFree( pidlDesktop );
 }
 
 /******************************************************************************
@@ -221,6 +244,7 @@ static BOOL GetName(LPSHELLFOLDER lpsf, 
  * InsertTreeViewItem [Internal]
  *
  * PARAMS
+ *  info       [I] data for the dialog
  *  lpsf       [I] IShellFolder interface of the item's parent shell folder 
  *  pidl       [I] ITEMIDLIST of the child to insert, relativ to parent 
  *  pidlParent [I] ITEMIDLIST of the parent shell folder
@@ -231,8 +255,9 @@ static BOOL GetName(LPSHELLFOLDER lpsf, 
  *  Success: Handle to the created and inserted treeview-item
  *  Failure: NULL
  */
-static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl, 
-    LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM hParent)
+static HTREEITEM InsertTreeViewItem( browse_info *info, IShellFolder * lpsf,
+    LPCITEMIDLIST pidl, LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL,
+    HTREEITEM hParent)
 {
 	TVITEMW 	tvi;
 	TVINSERTSTRUCTW	tvins;
@@ -244,7 +269,8 @@ static HTREEITEM InsertTreeViewItem(IShe
 	tvi.cChildren= pEnumIL ? 1 : 0;
 	tvi.mask |= TVIF_CHILDREN;
 
-	if (!(lptvid = (LPTV_ITEMDATA)SHAlloc(sizeof(TV_ITEMDATA))))
+	lptvid = SHAlloc( sizeof(TV_ITEMDATA) );
+	if (!lptvid)
 	    return NULL;
 
 	if (!GetName(lpsf, pidl, SHGDN_NORMAL, szBuff))
@@ -265,7 +291,7 @@ static HTREEITEM InsertTreeViewItem(IShe
 	tvins.hInsertAfter = NULL;
 	tvins.hParent      = hParent;
 
-	return (HTREEITEM)TreeView_InsertItemW(hwndTreeView, &tvins);
+	return (HTREEITEM)TreeView_InsertItemW( info->hwndTreeView, &tvins );
 }
 
 /******************************************************************************
@@ -275,26 +301,28 @@ static HTREEITEM InsertTreeViewItem(IShe
  * lpsf and whose PIDL is pidl, insert a treeview-item right under hParent
  *
  * PARAMS
+ *  info    [I] data for the dialog
  *  lpsf    [I] IShellFolder interface of the parent shell folder
  *  pidl    [I] ITEMIDLIST of the parent shell folder
  *  hParent [I] The treeview item that represents the parent shell folder
  *  lpe     [I] An iterator for the children of the parent shell folder
  */
-static void FillTreeView(IShellFolder * lpsf, LPITEMIDLIST  pidl, HTREEITEM hParent, IEnumIDList* lpe)
+static void FillTreeView( browse_info *info, IShellFolder * lpsf,
+                 LPITEMIDLIST  pidl, HTREEITEM hParent, IEnumIDList* lpe)
 {
 	HTREEITEM	hPrev = 0;
 	LPITEMIDLIST	pidlTemp = 0;
 	ULONG		ulFetched;
 	HRESULT		hr;
-	HWND		hwnd=GetParent(hwndTreeView);
+	HWND		hwnd = GetParent( info->hwndTreeView );
 
 	TRACE("%p %p %x %p\n",lpsf, pidl, (INT)hParent, lpe);
 
 	/* No IEnumIDList -> No children */
 	if (!lpe) return;
 	
-	SetCapture(GetParent(hwndTreeView));
-	SetCursor(LoadCursorA(0, (LPSTR)IDC_WAIT));
+	SetCapture( hwnd );
+	SetCursor( LoadCursorA( 0, (LPSTR)IDC_WAIT ) );
 
 	while (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched))
 	{
@@ -307,10 +335,12 @@ static void FillTreeView(IShellFolder * 
 	        hr = IShellFolder_BindToObject(lpsf,pidlTemp,NULL,&IID_IShellFolder,(LPVOID*)&pSFChild);
 	        if (SUCCEEDED(hr))
                 {
-	            hr = IShellFolder_EnumObjects(pSFChild, hwnd, BrowseFlagsToSHCONTF(lpBrowseInfo->ulFlags), &pEnumIL);
+	            DWORD flags = BrowseFlagsToSHCONTF(info->lpBrowseInfo->ulFlags);
+	            hr = IShellFolder_EnumObjects(pSFChild, hwnd, flags, &pEnumIL);
                     if (hr == S_OK)
                     {
-                        if ((IEnumIDList_Skip(pEnumIL, 1) != S_OK) || FAILED(IEnumIDList_Reset(pEnumIL)))
+                        if ((IEnumIDList_Skip(pEnumIL, 1) != S_OK) ||
+                             FAILED(IEnumIDList_Reset(pEnumIL)))
                         {
                             IEnumIDList_Release(pEnumIL);
                             pEnumIL = NULL;
@@ -320,13 +350,13 @@ static void FillTreeView(IShellFolder * 
                 }
 	    }
 
-	    if (!(hPrev = InsertTreeViewItem(lpsf, pidlTemp, pidl, pEnumIL, hParent)))
-	        goto Done;
+	    if (!(hPrev = InsertTreeViewItem(info, lpsf, pidlTemp, pidl, pEnumIL, hParent)))
+	        goto done;
 	    SHFree(pidlTemp);  /* Finally, free the pidl that the shell gave us... */
 	    pidlTemp=NULL;
 	}
 
-Done:
+done:
 	ReleaseCapture();
 	SetCursor(LoadCursorW(0, (LPWSTR)IDC_ARROW));
 
@@ -342,8 +372,9 @@ static inline BOOL PIDLIsType(LPCITEMIDL
     return (data->type == type);
 }
 
-static void BrsFolder_CheckValidSelection(HWND hWndTree, LPTV_ITEMDATA lptvid)
+static void BrsFolder_CheckValidSelection( browse_info *info, LPTV_ITEMDATA lptvid )
 {
+    LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
     LPCITEMIDLIST pidl = lptvid->lpi;
     BOOL bEnabled = TRUE;
     DWORD dwAttributes;
@@ -368,10 +399,10 @@ static void BrsFolder_CheckValidSelectio
         if (FAILED(r) || (dwAttributes != (SFGAO_FOLDER | SFGAO_FILESYSTEM)))
             bEnabled = FALSE;
     }
-    SendMessageW(hWndTree, BFFM_ENABLEOK, 0, (LPARAM)bEnabled);
+    SendMessageW(info->hWnd, BFFM_ENABLEOK, 0, (LPARAM)bEnabled);
 }
 
-static LRESULT BrsFolder_Treeview_Delete( NMTREEVIEWW *pnmtv )
+static LRESULT BrsFolder_Treeview_Delete( browse_info *info, NMTREEVIEWW *pnmtv )
 {
     LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA)pnmtv->itemOld.lParam;
 
@@ -386,7 +417,7 @@ static LRESULT BrsFolder_Treeview_Delete
     return 0;
 }
 
-static LRESULT BrsFolder_Treeview_Expand( NMTREEVIEWW *pnmtv )
+static LRESULT BrsFolder_Treeview_Expand( browse_info *info, NMTREEVIEWW *pnmtv )
 {
     IShellFolder *lpsf2 = NULL;
     LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
@@ -400,33 +431,33 @@ static LRESULT BrsFolder_Treeview_Expand
     r = IShellFolder_BindToObject( lptvid->lpsfParent, lptvid->lpi, 0,
                                   (REFIID)&IID_IShellFolder, (LPVOID *)&lpsf2 );
     if (SUCCEEDED(r))
-        FillTreeView( lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem, lptvid->pEnumIL);
+        FillTreeView( info, lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem, lptvid->pEnumIL);
 
     /* My Computer is already sorted and trying to do a simple text
      * sort will only mess things up */
     if (!_ILIsMyComputer(lptvid->lpi))
-        TreeView_SortChildren(hwndTreeView, pnmtv->itemNew.hItem, FALSE);
+        TreeView_SortChildren(info->hwndTreeView, pnmtv->itemNew.hItem, FALSE);
 
     return 0;
 }
 
-static HRESULT BrsFolder_Treeview_Changed( HWND hWnd, NMTREEVIEWW *pnmtv )
+static HRESULT BrsFolder_Treeview_Changed( browse_info *info, NMTREEVIEWW *pnmtv )
 {
     LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
 
     lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
-    pidlRet = lptvid->lpifq;
-    if (lpBrowseInfo->lpfn)
-        (lpBrowseInfo->lpfn)(hWnd, BFFM_SELCHANGED, (LPARAM)pidlRet, lpBrowseInfo->lParam);
-    BrsFolder_CheckValidSelection(hWnd, lptvid);
+    info->pidlRet = lptvid->lpifq;
+    browsefolder_callback( info->lpBrowseInfo, info->hWnd, BFFM_SELCHANGED,
+                           (LPARAM)info->pidlRet );
+    BrsFolder_CheckValidSelection( info, lptvid );
     return 0;
 }
 
-static LRESULT BrsFolder_OnNotify( HWND hWnd, UINT CtlID, LPNMHDR lpnmh )
+static LRESULT BrsFolder_OnNotify( browse_info *info, UINT CtlID, LPNMHDR lpnmh )
 {
     NMTREEVIEWW *pnmtv = (NMTREEVIEWW *)lpnmh;
 
-    TRACE("%p %x %p msg=%x\n", hWnd,  CtlID, lpnmh, pnmtv->hdr.code);
+    TRACE("%p %x %p msg=%x\n", info, CtlID, lpnmh, pnmtv->hdr.code);
 
     if (pnmtv->hdr.idFrom != IDD_TREEVIEW)
         return 0;
@@ -435,15 +466,15 @@ static LRESULT BrsFolder_OnNotify( HWND 
     {
     case TVN_DELETEITEMA:
     case TVN_DELETEITEMW:
-        return BrsFolder_Treeview_Delete( pnmtv );
+        return BrsFolder_Treeview_Delete( info, pnmtv );
 
     case TVN_ITEMEXPANDINGA:
     case TVN_ITEMEXPANDINGW:
-        return BrsFolder_Treeview_Expand( pnmtv );
+        return BrsFolder_Treeview_Expand( info, pnmtv );
 
     case TVN_SELCHANGEDA:
     case TVN_SELCHANGEDW:
-        return BrsFolder_Treeview_Changed( hWnd, pnmtv );
+        return BrsFolder_Treeview_Changed( info, pnmtv );
 
     default:
         WARN("unhandled (%d)\n", pnmtv->hdr.code);
@@ -454,10 +485,12 @@ static LRESULT BrsFolder_OnNotify( HWND 
 }
 
 
-static BOOL BrsFolder_OnCreate( HWND hWnd, LPBROWSEINFOW lpbi )
+static BOOL BrsFolder_OnCreate( HWND hWnd, browse_info *info )
 {
-    pidlRet = NULL;
-    lpBrowseInfo = lpbi;
+    LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
+
+    info->hWnd = hWnd;
+    SetPropW( hWnd, szBrowseFolderInfo, info );
 
     if (lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS)
 	FIXME("flags %x not implemented\n", lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS);
@@ -470,27 +503,32 @@ static BOOL BrsFolder_OnCreate( HWND hWn
     if (!(lpBrowseInfo->ulFlags & BIF_STATUSTEXT))
 	ShowWindow( GetDlgItem(hWnd, IDD_STATUS), SW_HIDE );
 
-    InitializeTreeView( hWnd, lpBrowseInfo->pidlRoot );
+    info->hwndTreeView = GetDlgItem( hWnd, IDD_TREEVIEW );
+    if (info->hwndTreeView)
+        InitializeTreeView( info );
+    else
+        ERR("treeview control missing!\n");
 
-    if (lpBrowseInfo->lpfn)
-	(lpBrowseInfo->lpfn)( hWnd, BFFM_INITIALIZED, 0, lpBrowseInfo->lParam );
+    browsefolder_callback( info->lpBrowseInfo, hWnd, BFFM_INITIALIZED, 0 );
 
     return TRUE;
 }
 
-static BOOL BrsFolder_OnCommand( HWND hWnd, UINT id )
+static BOOL BrsFolder_OnCommand( browse_info *info, UINT id )
 {
+    LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
+
     switch (id)
     {
     case IDOK:
-        pdump( pidlRet );
+        pdump( info->pidlRet );
         if (lpBrowseInfo->pszDisplayName)
-            SHGetPathFromIDListW( pidlRet, lpBrowseInfo->pszDisplayName );
-        EndDialog(hWnd, (DWORD) ILClone(pidlRet));
+            SHGetPathFromIDListW( info->pidlRet, lpBrowseInfo->pszDisplayName );
+        EndDialog( info->hWnd, 1 );
         return TRUE;
 
     case IDCANCEL:
-        EndDialog(hWnd, 0);
+        EndDialog( info->hWnd, 0 );
         return TRUE;
     }
     return FALSE;
@@ -502,18 +540,22 @@ static BOOL BrsFolder_OnCommand( HWND hW
 static INT_PTR CALLBACK BrsFolderDlgProc( HWND hWnd, UINT msg, WPARAM wParam,
 				          LPARAM lParam )
 {
+    browse_info *info;
+
     TRACE("hwnd=%p msg=%04x 0x%08x 0x%08lx\n", hWnd,  msg, wParam, lParam );
 
     if (msg == WM_INITDIALOG)
-        return BrsFolder_OnCreate( hWnd, (LPBROWSEINFOW) lParam );
+        return BrsFolder_OnCreate( hWnd, (browse_info*) lParam );
+
+    info = (browse_info*) GetPropW( hWnd, szBrowseFolderInfo );
 
     switch (msg)
     {
     case WM_NOTIFY:
-        return BrsFolder_OnNotify( hWnd, (UINT)wParam, (LPNMHDR)lParam);
+        return BrsFolder_OnNotify( info, (UINT)wParam, (LPNMHDR)lParam);
 
     case WM_COMMAND:
-        return BrsFolder_OnCommand( hWnd, wParam );
+        return BrsFolder_OnCommand( info, wParam );
 
     case BFFM_SETSTATUSTEXTA:
         TRACE("Set status %s\n", debugstr_a((LPSTR)lParam));
@@ -559,7 +601,7 @@ static INT_PTR CALLBACK BrsFolderDlgProc
     return FALSE;
 }
 
-static const WCHAR swBrowseTempName[] = {
+static const WCHAR swBrowseTemplateName[] = {
     'S','H','B','R','S','F','O','R','F','O','L','D','E','R','_','M','S','G','B','O','X',0};
 
 /*************************************************************************
@@ -568,66 +610,71 @@ static const WCHAR swBrowseTempName[] = 
  */
 LPITEMIDLIST WINAPI SHBrowseForFolderA (LPBROWSEINFOA lpbi)
 {
-	BROWSEINFOW bi;
-	LPITEMIDLIST lpid;
-	INT len;
-	
-	TRACE("(%p{lpszTitle=%s,owner=%p})\n", lpbi,
-	    lpbi ? debugstr_a(lpbi->lpszTitle) : NULL, lpbi ? lpbi->hwndOwner : NULL);
-
-	if (!lpbi)
-	  return NULL;
+    BROWSEINFOW bi;
+    LPITEMIDLIST lpid;
+    INT len;
+    
+    TRACE("%p\n", lpbi);
 
-	bi.hwndOwner = lpbi->hwndOwner;
-	bi.pidlRoot = lpbi->pidlRoot;
-	if (lpbi->pszDisplayName)
-	{
-	  /*lpbi->pszDisplayName is assumed to be MAX_PATH (MSDN) */
-	  bi.pszDisplayName = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
-	  MultiByteToWideChar(CP_ACP, 0, lpbi->pszDisplayName, -1, bi.pszDisplayName, MAX_PATH);
-	}
-	else
-	  bi.pszDisplayName = NULL;
+    bi.hwndOwner = lpbi->hwndOwner;
+    bi.pidlRoot = lpbi->pidlRoot;
+    if (lpbi->pszDisplayName)
+    {
+        len = MultiByteToWideChar( CP_ACP, 0, lpbi->pszDisplayName, -1, NULL, 0 );
+        bi.pszDisplayName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        MultiByteToWideChar( CP_ACP, 0, lpbi->pszDisplayName, -1, bi.pszDisplayName, len );
+    }
+    else
+        bi.pszDisplayName = NULL;
 
-	if (lpbi->lpszTitle)
-	{
-	  len = MultiByteToWideChar(CP_ACP, 0, lpbi->lpszTitle, -1, NULL, 0);
-	  bi.lpszTitle = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-	  MultiByteToWideChar(CP_ACP, 0, lpbi->lpszTitle, -1, (LPWSTR)bi.lpszTitle, len);
-	}
-	else
-	  bi.lpszTitle = NULL;
+    if (lpbi->lpszTitle)
+    {
+        len = MultiByteToWideChar( CP_ACP, 0, lpbi->lpszTitle, -1, NULL, 0 );
+        bi.lpszTitle = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        MultiByteToWideChar( CP_ACP, 0, lpbi->lpszTitle, -1, (LPWSTR)bi.lpszTitle, len );
+    }
+    else
+        bi.lpszTitle = NULL;
 
-	bi.ulFlags = lpbi->ulFlags;
-	bi.lpfn = lpbi->lpfn;
-	bi.lParam = lpbi->lParam;
-	bi.iImage = lpbi->iImage;
-	lpid = (LPITEMIDLIST) DialogBoxParamW(shell32_hInstance,
-	                                      swBrowseTempName, lpbi->hwndOwner,
-	                                      BrsFolderDlgProc, (INT)&bi);
-	if (bi.pszDisplayName)
-	{
-	  WideCharToMultiByte(CP_ACP, 0, bi.pszDisplayName, -1, lpbi->pszDisplayName, MAX_PATH, 0, NULL);
-	  HeapFree(GetProcessHeap(), 0, bi.pszDisplayName);
-	}
-        HeapFree(GetProcessHeap(), 0, (LPVOID)bi.lpszTitle);
-	lpbi->iImage = bi.iImage;
-	return lpid;
+    bi.ulFlags = lpbi->ulFlags;
+    bi.lpfn = lpbi->lpfn;
+    bi.lParam = lpbi->lParam;
+    bi.iImage = lpbi->iImage;
+    lpid = SHBrowseForFolderW( &bi );
+    if (bi.pszDisplayName)
+    {
+        WideCharToMultiByte( CP_ACP, 0, bi.pszDisplayName, -1,
+                             lpbi->pszDisplayName, MAX_PATH, 0, NULL);
+        HeapFree( GetProcessHeap(), 0, bi.pszDisplayName );
+    }
+    HeapFree(GetProcessHeap(), 0, (LPVOID)bi.lpszTitle);
+    lpbi->iImage = bi.iImage;
+    return lpid;
 }
 
 
 /*************************************************************************
  * SHBrowseForFolderW [SHELL32.@]
+ *
+ * NOTES:
+ *  crashes when passed a null pointer
  */
 LPITEMIDLIST WINAPI SHBrowseForFolderW (LPBROWSEINFOW lpbi)
 {
-	TRACE("((%p->{lpszTitle=%s,owner=%p})\n", lpbi,
-	    lpbi ? debugstr_w(lpbi->lpszTitle) : NULL, lpbi ? lpbi->hwndOwner : 0);
+    browse_info info;
+    DWORD r;
+
+    ERR("%p\n", lpbi);
 
-	if (!lpbi)
-	  return NULL;
+    info.hWnd = 0;
+    info.pidlRet = NULL;
+    info.lpBrowseInfo = lpbi;
+    info.hwndTreeView = NULL;
+
+    r = DialogBoxParamW( shell32_hInstance, swBrowseTemplateName, lpbi->hwndOwner,
+	                 BrsFolderDlgProc, (LPARAM)&info );
+    if (!r)
+        return NULL;
 
-	return (LPITEMIDLIST) DialogBoxParamW(shell32_hInstance,
-	                                      swBrowseTempName, lpbi->hwndOwner,
-	                                      BrsFolderDlgProc, (INT)lpbi);
+    return info.pidlRet;
 }


More information about the wine-patches mailing list