Fixed off by one allocation error (DPA and DSA).
[wine] / dlls / commdlg / filedlgbrowser.c
1 /*
2  *  Implementation of IShellBrowser for the File Open common dialog
3  * 
4  *
5  */
6
7 #include <stdio.h>
8 #include "unknwn.h"
9 #include "filedlgbrowser.h"
10 #include "winuser.h"
11 #include "heap.h"
12 #include "wine/obj_dataobject.h"
13 #include "debugtools.h"
14 #include "cdlg.h"
15 #include "wine/undocshell.h"
16
17 DEFAULT_DEBUG_CHANNEL(commdlg)
18
19 #define SETDefFormatEtc(fe,cf,med) \
20 { \
21     (fe).cfFormat = cf;\
22     (fe).dwAspect = DVASPECT_CONTENT; \
23     (fe).ptd =NULL;\
24     (fe).tymed = med;\
25     (fe).lindex = -1;\
26 };
27
28
29 /**************************************************************************
30 *   Structure
31 */
32 static ICOM_VTABLE(IShellBrowser) IShellBrowserImpl_Vtbl =
33 {
34         /* IUnknown */
35         IShellBrowserImpl_QueryInterface,
36         IShellBrowserImpl_AddRef,
37         IShellBrowserImpl_Release,
38         /* IOleWindow */
39         IShellBrowserImpl_GetWindow,
40         IShellBrowserImpl_ContextSensitiveHelp,
41         /*  IShellBrowser */
42         IShellBrowserImpl_InsertMenusSB,
43         IShellBrowserImpl_SetMenuSB,
44         IShellBrowserImpl_RemoveMenusSB,
45         IShellBrowserImpl_SetStatusTextSB,
46         IShellBrowserImpl_EnableModelessSB,
47         IShellBrowserImpl_TranslateAcceleratorSB,
48         IShellBrowserImpl_BrowseObject,
49         IShellBrowserImpl_GetViewStateStream,
50         IShellBrowserImpl_GetControlWindow,
51         IShellBrowserImpl_SendControlMsg,
52         IShellBrowserImpl_QueryActiveShellView,
53         IShellBrowserImpl_OnViewWindowActive,
54         IShellBrowserImpl_SetToolbarItems
55 };
56
57 static ICOM_VTABLE(ICommDlgBrowser) IShellBrowserImpl_ICommDlgBrowser_Vtbl =
58 {
59         /* IUnknown */
60         IShellBrowserImpl_ICommDlgBrowser_QueryInterface,
61         IShellBrowserImpl_ICommDlgBrowser_AddRef,
62         IShellBrowserImpl_ICommDlgBrowser_Release,
63         /* ICommDlgBrowser */
64         IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand,
65         IShellBrowserImpl_ICommDlgBrowser_OnStateChange,
66         IShellBrowserImpl_ICommDlgBrowser_IncludeObject
67 };
68
69
70 /**************************************************************************
71 *   Local Prototypes
72 */
73
74 HRESULT IShellBrowserImpl_ICommDlgBrowser_OnSelChange(ICommDlgBrowser *iface, IShellView *ppshv);
75 //LPITEMIDLIST GetSelectedPidl(IShellView *ppshv);
76
77 /**************************************************************************
78 *   External Prototypes
79 */
80 extern const char *FileOpenDlgInfosStr; 
81
82 extern HRESULT          GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPSTR lpstrFileName);
83 extern HRESULT          GetFileName(HWND hwnd, LPITEMIDLIST pidl, LPSTR lpstrFileName);
84 extern IShellFolder*    GetShellFolderFromPidl(LPITEMIDLIST pidlAbs);
85 extern LPITEMIDLIST     GetParentPidl(LPITEMIDLIST pidl);
86 extern LPITEMIDLIST     GetPidlFromName(IShellFolder *psf,LPCSTR lpcstrFileName);
87
88 extern BOOL    FILEDLG95_SHELL_FillIncludedItemList(HWND hwnd,
89                                                         LPITEMIDLIST pidlCurrentFolder,
90                                                         LPSTR lpstrMask);
91
92 extern int     FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl);
93 extern BOOL    FILEDLG95_OnOpen(HWND hwnd);
94
95
96 /**************************************************************************
97 *  IShellBrowserImpl_Construct
98 */
99 IShellBrowser * IShellBrowserImpl_Construct(HWND hwndOwner)
100 {
101     IShellBrowserImpl *sb;
102     FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwndOwner,FileOpenDlgInfosStr);
103
104     sb=(IShellBrowserImpl*)SHAlloc(sizeof(IShellBrowserImpl));
105
106     /* Initialisation of the member variables */
107     sb->ref=1;
108     sb->hwndOwner = hwndOwner;
109
110     /* Initialisation of the vTables */
111     sb->lpVtbl = &IShellBrowserImpl_Vtbl;
112     sb->lpVtbl2 = &IShellBrowserImpl_ICommDlgBrowser_Vtbl;
113
114     COMDLG32_SHGetSpecialFolderLocation(hwndOwner,
115                                CSIDL_DESKTOP,
116                                &fodInfos->ShellInfos.pidlAbsCurrent);
117
118     TRACE("%p\n", sb);
119
120     return (IShellBrowser *) sb;
121 }
122
123 /**************************************************************************
124 *
125 *
126 *  The INTERFACE of the IShellBrowser object
127 *
128 */
129
130 /*
131  * IUnknown
132  */
133
134 /***************************************************************************
135 *  IShellBrowserImpl_QueryInterface
136 */
137 HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
138                                             REFIID riid, 
139                                             LPVOID *ppvObj)
140 {
141     ICOM_THIS(IShellBrowserImpl, iface);
142
143     TRACE("(%p)\n", This);
144
145     *ppvObj = NULL;
146
147     if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
148     { *ppvObj = This; 
149     }
150     else if(IsEqualIID(riid, &IID_IOleWindow))  /*IOleWindow*/
151     { *ppvObj = (IOleWindow*)This;
152     }
153
154     else if(IsEqualIID(riid, &IID_IShellBrowser))  /*IShellBrowser*/
155     { *ppvObj = (IShellBrowser*)This;
156     }
157
158     else if(IsEqualIID(riid, &IID_ICommDlgBrowser))  /*ICommDlgBrowser*/
159     { *ppvObj = (ICommDlgBrowser*) &(This->lpVtbl2);
160     }
161
162     if(*ppvObj)
163     { IUnknown_AddRef( (IShellBrowser*) *ppvObj);
164       return S_OK;
165     }
166     return E_NOINTERFACE;
167 }
168
169 /**************************************************************************
170 *  IShellBrowser::AddRef
171 */
172 ULONG WINAPI IShellBrowserImpl_AddRef(IShellBrowser * iface)
173 {
174     ICOM_THIS(IShellBrowserImpl, iface);
175
176     TRACE("(%p)\n", This);
177
178     return ++(This->ref);
179 }
180
181 /**************************************************************************
182 *  IShellBrowserImpl_Release
183 */
184 ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
185 {
186     ICOM_THIS(IShellBrowserImpl, iface);
187
188     TRACE("(%p)\n", This);
189
190     if (!--(This->ref)) 
191     { 
192       COMDLG32_SHFree(This);
193       return 0;
194     }
195     return This->ref;
196 }
197
198 /*
199  * IOleWindow
200  */
201
202 /**************************************************************************
203 *  IShellBrowserImpl_GetWindow  (IOleWindow)
204 *
205 *  Inherited from IOleWindow::GetWindow
206 *
207 *  See Windows documentation for more details
208 *
209 *  Note : We will never be window less in the File Open dialog
210 *  
211 */
212 HRESULT WINAPI IShellBrowserImpl_GetWindow(IShellBrowser * iface,  
213                                            HWND * phwnd)
214 {
215     ICOM_THIS(IShellBrowserImpl, iface);
216
217     TRACE("(%p)\n", This);
218
219     if(!This->hwndOwner)
220         return E_FAIL;
221
222     *phwnd = This->hwndOwner;
223
224     return (*phwnd) ? S_OK : E_UNEXPECTED; 
225
226 }
227
228 /**************************************************************************
229 *  IShellBrowserImpl_ContextSensitiveHelp
230 */
231 HRESULT WINAPI IShellBrowserImpl_ContextSensitiveHelp(IShellBrowser * iface,
232                                                       BOOL fEnterMode)
233 {
234     ICOM_THIS(IShellBrowserImpl, iface);
235
236     TRACE("(%p)\n", This);
237
238     /* Feature not implemented */
239     return E_NOTIMPL;
240 }
241
242 /*
243  * IShellBrowser
244  */
245
246 /**************************************************************************
247 *  IShellBrowserImpl_BrowseObject
248 *
249 *  See Windows documentation on IShellBrowser::BrowseObject for more details
250 *
251 *  This function will override user specified flags and will always 
252 *  use SBSP_DEFBROWSER and SBSP_DEFMODE.  
253 */
254 HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface, 
255                                               LPCITEMIDLIST pidl, 
256                                               UINT wFlags)
257 {
258     HRESULT hRes;
259     IShellFolder *psfTmp;
260     IShellView *psvTmp;
261     FileOpenDlgInfos *fodInfos;
262     LPITEMIDLIST pidlTmp;
263
264     ICOM_THIS(IShellBrowserImpl, iface);
265
266     TRACE("(%p)\n", This);
267
268     fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
269
270     /* Format the pidl according to its parameter's category */
271     if(wFlags & SBSP_RELATIVE)
272     {
273         
274         /* SBSP_RELATIVE  A relative pidl (relative from the current folder) */
275         hRes = IShellFolder_BindToObject(fodInfos->Shell.FOIShellFolder,
276                                      pidl,
277                                      NULL,
278                                      &IID_IShellFolder,
279                                      (LPVOID *)&psfTmp);
280         if(FAILED(hRes))
281         {
282             return hRes;
283         }
284         /* create an absolute pidl */
285         pidlTmp = COMDLG32_PIDL_ILCombine(fodInfos->ShellInfos.pidlAbsCurrent,
286                                                         (LPITEMIDLIST)pidl);
287         
288     }
289     else if(wFlags & SBSP_PARENT)
290     {
291         /* Browse the parent folder (ignores the pidl) */
292         
293         pidlTmp = GetParentPidl(fodInfos->ShellInfos.pidlAbsCurrent);
294         psfTmp = GetShellFolderFromPidl(pidlTmp);
295
296     }
297     else
298     {
299         /* An absolute pidl (relative from the desktop) */
300         pidlTmp =  COMDLG32_PIDL_ILClone((LPITEMIDLIST)pidl);
301         psfTmp = GetShellFolderFromPidl(pidlTmp);
302     }
303
304     
305     /* Retrieve the IShellFolder interface of the pidl specified folder */
306     if(!psfTmp)
307         return E_FAIL;
308
309     /* Release the current fodInfos->Shell.FOIShellFolder and update its value */
310     IShellFolder_Release(fodInfos->Shell.FOIShellFolder);
311     fodInfos->Shell.FOIShellFolder = psfTmp;
312
313     /* Create the associated view */
314     if(SUCCEEDED(hRes = IShellFolder_CreateViewObject(psfTmp,
315                                                       fodInfos->ShellInfos.hwndOwner,
316                                                       &IID_IShellView,
317                                                       (LPVOID *)&psvTmp)))
318     {
319         HWND hwndView;
320         /* Get the foldersettings from the old view */
321         if(fodInfos->Shell.FOIShellView)
322         { 
323           IShellView_GetCurrentInfo(fodInfos->Shell.FOIShellView, 
324                                   &fodInfos->ShellInfos.folderSettings);
325         }
326
327         /* Create the window */
328         if(SUCCEEDED(hRes = IShellView_CreateViewWindow(psvTmp,
329                                           NULL,
330                                           &fodInfos->ShellInfos.folderSettings,
331                                           fodInfos->Shell.FOIShellBrowser,
332                                           &fodInfos->ShellInfos.rectView,
333                                           &hwndView)))
334         {
335             /* Fit the created view in the appropriate RECT */
336             MoveWindow(hwndView,
337                        fodInfos->ShellInfos.rectView.left,
338                        fodInfos->ShellInfos.rectView.top,
339                        fodInfos->ShellInfos.rectView.right-fodInfos->ShellInfos.rectView.left,
340                        fodInfos->ShellInfos.rectView.bottom-fodInfos->ShellInfos.rectView.top,
341                        FALSE);
342
343             /* Select the new folder in the Look In combo box of the Open file dialog */
344             
345             FILEDLG95_LOOKIN_SelectItem(fodInfos->DlgInfos.hwndLookInCB,pidlTmp);
346
347             /* Release old pidlAbsCurrent memory and update its value */
348             COMDLG32_SHFree((LPVOID)fodInfos->ShellInfos.pidlAbsCurrent);
349             fodInfos->ShellInfos.pidlAbsCurrent = pidlTmp;
350
351             /* Release the current fodInfos->Shell.FOIShellView and update its value */
352             if(fodInfos->Shell.FOIShellView)
353             {
354                 IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView);
355                 IShellView_Release(fodInfos->Shell.FOIShellView);
356             }
357 #if 0
358             ShowWindow(fodInfos->ShellInfos.hwndView,SW_HIDE);
359 #endif
360             fodInfos->Shell.FOIShellView = psvTmp;
361
362             fodInfos->ShellInfos.hwndView = hwndView;
363             
364             return NOERROR;
365         }
366     }
367
368     FILEDLG95_LOOKIN_SelectItem(fodInfos->DlgInfos.hwndLookInCB,fodInfos->ShellInfos.pidlAbsCurrent);
369     return hRes; 
370 }
371
372 /**************************************************************************
373 *  IShellBrowserImpl_EnableModelessSB
374 */
375 HRESULT WINAPI IShellBrowserImpl_EnableModelessSB(IShellBrowser *iface,    
376                                               BOOL fEnable)
377                                               
378 {
379     ICOM_THIS(IShellBrowserImpl, iface);
380
381     TRACE("(%p)\n", This);
382
383     /* Feature not implemented */
384     return E_NOTIMPL;
385 }
386
387 /**************************************************************************
388 *  IShellBrowserImpl_GetControlWindow
389 */
390 HRESULT WINAPI IShellBrowserImpl_GetControlWindow(IShellBrowser *iface,    
391                                               UINT id,    
392                                               HWND *lphwnd)
393                                               
394 {
395     ICOM_THIS(IShellBrowserImpl, iface);
396
397     TRACE("(%p)\n", This);
398
399     /* Feature not implemented */
400     return E_NOTIMPL;
401 }
402 /**************************************************************************
403 *  IShellBrowserImpl_GetViewStateStream
404 */
405 HRESULT WINAPI IShellBrowserImpl_GetViewStateStream(IShellBrowser *iface,
406                                                 DWORD grfMode,    
407                                                 LPSTREAM *ppStrm)
408                                               
409 {
410     ICOM_THIS(IShellBrowserImpl, iface);
411
412     TRACE("(%p)\n", This);
413
414     /* Feature not implemented */
415     return E_NOTIMPL;
416 }       
417 /**************************************************************************
418 *  IShellBrowserImpl_InsertMenusSB
419 */
420 HRESULT WINAPI IShellBrowserImpl_InsertMenusSB(IShellBrowser *iface,
421                                            HMENU hmenuShared,
422                                            LPOLEMENUGROUPWIDTHS lpMenuWidths)
423                                               
424 {
425     ICOM_THIS(IShellBrowserImpl, iface);
426
427     TRACE("(%p)\n", This);
428
429     /* Feature not implemented */
430     return E_NOTIMPL;
431 }
432 /**************************************************************************
433 *  IShellBrowserImpl_OnViewWindowActive
434 */
435 HRESULT WINAPI IShellBrowserImpl_OnViewWindowActive(IShellBrowser *iface,
436                                                 IShellView *ppshv)
437                                               
438 {
439     ICOM_THIS(IShellBrowserImpl, iface);
440
441     TRACE("(%p)\n", This);
442
443     /* Feature not implemented */
444     return E_NOTIMPL;
445 }   
446 /**************************************************************************
447 *  IShellBrowserImpl_QueryActiveShellView
448 */
449 HRESULT WINAPI IShellBrowserImpl_QueryActiveShellView(IShellBrowser *iface,
450                                                   IShellView **ppshv)
451                                               
452 {
453     ICOM_THIS(IShellBrowserImpl, iface);
454
455     FileOpenDlgInfos *fodInfos;
456
457     TRACE("(%p)\n", This);
458
459     fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
460
461     if(!(*ppshv = fodInfos->Shell.FOIShellView))
462     {
463         return E_FAIL;
464     }
465     IShellView_AddRef(fodInfos->Shell.FOIShellView);
466     return NOERROR;
467 }   
468 /**************************************************************************
469 *  IShellBrowserImpl_RemoveMenusSB
470 */
471 HRESULT WINAPI IShellBrowserImpl_RemoveMenusSB(IShellBrowser *iface,
472                                            HMENU hmenuShared)
473                                               
474 {
475     ICOM_THIS(IShellBrowserImpl, iface);
476
477     TRACE("(%p)\n", This);
478
479     /* Feature not implemented */
480     return E_NOTIMPL;
481 }   
482 /**************************************************************************
483 *  IShellBrowserImpl_SendControlMsg
484 */
485 HRESULT WINAPI IShellBrowserImpl_SendControlMsg(IShellBrowser *iface,    
486                                             UINT id,    
487                                             UINT uMsg,    
488                                             WPARAM wParam,    
489                                             LPARAM lParam,
490                                             LRESULT *pret)
491                                               
492 {
493     ICOM_THIS(IShellBrowserImpl, iface);
494
495     TRACE("(%p)\n", This);
496
497     /* Feature not implemented */
498     return E_NOTIMPL;
499 }
500 /**************************************************************************
501 *  IShellBrowserImpl_SetMenuSB
502 */
503 HRESULT WINAPI IShellBrowserImpl_SetMenuSB(IShellBrowser *iface,
504                                        HMENU hmenuShared,    
505                                        HOLEMENU holemenuReserved,
506                                        HWND hwndActiveObject)
507                                               
508 {
509     ICOM_THIS(IShellBrowserImpl, iface);
510
511     TRACE("(%p)\n", This);
512
513     /* Feature not implemented */
514     return E_NOTIMPL;
515 }   
516 /**************************************************************************
517 *  IShellBrowserImpl_SetStatusTextSB
518 */
519 HRESULT WINAPI IShellBrowserImpl_SetStatusTextSB(IShellBrowser *iface,
520                                              LPCOLESTR lpszStatusText)
521                                               
522 {
523     ICOM_THIS(IShellBrowserImpl, iface);
524
525     TRACE("(%p)\n", This);
526
527     /* Feature not implemented */
528     return E_NOTIMPL;
529 }   
530 /**************************************************************************
531 *  IShellBrowserImpl_SetToolbarItems
532 */
533 HRESULT WINAPI IShellBrowserImpl_SetToolbarItems(IShellBrowser *iface,
534                                              LPTBBUTTON lpButtons,    
535                                              UINT nButtons,    
536                                              UINT uFlags)
537                                               
538 {
539     ICOM_THIS(IShellBrowserImpl, iface);
540
541     TRACE("(%p)\n", This);
542
543     /* Feature not implemented */
544     return E_NOTIMPL;
545 }   
546 /**************************************************************************
547 *  IShellBrowserImpl_TranslateAcceleratorSB
548 */
549 HRESULT WINAPI IShellBrowserImpl_TranslateAcceleratorSB(IShellBrowser *iface,
550                                                     LPMSG lpmsg,    
551                                                     WORD wID)
552                                               
553 {
554     ICOM_THIS(IShellBrowserImpl, iface);
555
556     TRACE("(%p)\n", This);
557
558     /* Feature not implemented */
559     return E_NOTIMPL;
560 }
561
562 /*
563  * ICommDlgBrowser
564  */
565
566 /***************************************************************************
567 *  IShellBrowserImpl_ICommDlgBrowser_QueryInterface
568 */
569 HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_QueryInterface(ICommDlgBrowser *iface,
570                                             REFIID riid, 
571                                             LPVOID *ppvObj)
572 {
573     _ICOM_THIS_FromICommDlgBrowser(IShellBrowser,iface);
574
575     TRACE("(%p)\n", This);
576
577     return IShellBrowserImpl_QueryInterface(This,riid,ppvObj);
578 }
579
580 /**************************************************************************
581 *  IShellBrowserImpl_ICommDlgBrowser_AddRef
582 */
583 ULONG WINAPI IShellBrowserImpl_ICommDlgBrowser_AddRef(ICommDlgBrowser * iface)
584 {
585     _ICOM_THIS_FromICommDlgBrowser(IShellBrowser,iface);
586
587     TRACE("(%p)\n", This);
588
589     return IShellBrowserImpl_AddRef(This);
590 }
591
592 /**************************************************************************
593 *  IShellBrowserImpl_ICommDlgBrowser_Release
594 */
595 ULONG WINAPI IShellBrowserImpl_ICommDlgBrowser_Release(ICommDlgBrowser * iface)
596 {
597     _ICOM_THIS_FromICommDlgBrowser(IShellBrowser,iface);
598
599     TRACE("(%p)\n", This);
600
601     return IShellBrowserImpl_Release(This);
602 }
603 /**************************************************************************
604 *  IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand
605 *
606 *   Called when a user double-clicks in the view or presses the ENTER key
607 */
608 HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnDefaultCommand(ICommDlgBrowser *iface,
609                                                                   IShellView *ppshv)
610 {
611     LPITEMIDLIST pidl;
612     FileOpenDlgInfos *fodInfos;
613
614     _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
615
616     TRACE("(%p)\n", This);
617
618     fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);  
619     
620     /* If the selected object is not a folder, send a IDOK command to parent window */
621     if((pidl = GetSelectedPidl(ppshv)))
622     {
623         HRESULT hRes;
624
625         ULONG  ulAttr = SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
626         IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidl, &ulAttr);
627         if (ulAttr)
628             hRes = IShellBrowser_BrowseObject((IShellBrowser *)This,pidl,SBSP_RELATIVE);
629         /* Tell the dialog that the user selected a file */
630         else
631         {
632             hRes = FILEDLG95_OnOpen(This->hwndOwner);
633         }
634
635         /* Free memory used by pidl */
636         COMDLG32_SHFree((LPVOID)pidl);
637
638         return hRes;
639     }
640
641     return E_FAIL;
642 }
643
644 /**************************************************************************
645 *  IShellBrowserImpl_ICommDlgBrowser_OnStateChange
646 */
647 HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnStateChange(ICommDlgBrowser *iface,
648                                                                IShellView *ppshv,
649                                                                ULONG uChange)
650 {
651
652     _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
653
654     TRACE("(%p)\n", This);
655
656     switch (uChange)
657     {
658         case CDBOSC_SETFOCUS:
659             break;
660         case CDBOSC_KILLFOCUS: 
661             {
662                 FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
663                 if(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
664                     SetDlgItemTextA(fodInfos->ShellInfos.hwndOwner,IDOK,"&Save");
665             }
666             break;
667         case CDBOSC_SELCHANGE:
668             return IShellBrowserImpl_ICommDlgBrowser_OnSelChange(iface,ppshv);
669         case CDBOSC_RENAME:
670             break;
671     }
672
673     return NOERROR;     
674 }
675 /**************************************************************************
676 *  IShellBrowserImpl_ICommDlgBrowser_IncludeObject
677 */
678 HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_IncludeObject(ICommDlgBrowser *iface, 
679                                                                IShellView * ppshv,
680                                                                LPCITEMIDLIST pidl)
681 {
682     FileOpenDlgInfos *fodInfos;
683     ULONG ulAttr;
684     STRRET str;
685     WCHAR szPathW[MAX_PATH];
686
687     _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
688
689     TRACE("(%p)\n", This);
690
691     fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
692
693     ulAttr = SFGAO_HIDDEN | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR | SFGAO_LINK;
694     IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidl, &ulAttr);
695     
696
697     if( (ulAttr & SFGAO_HIDDEN)                                         /* hidden */
698       | !(ulAttr & (SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR))) /* special folder */
699         return S_FALSE;
700     /* always include directorys and links */
701     if(ulAttr & (SFGAO_FOLDER | SFGAO_LINK)) 
702         return S_OK;
703     /* Check if there is a mask to apply if not */
704     if(!fodInfos->ShellInfos.lpstrCurrentFilter ||
705        !lstrlenW(fodInfos->ShellInfos.lpstrCurrentFilter))
706         return S_OK;
707
708     if (SUCCEEDED(IShellFolder_GetDisplayNameOf(fodInfos->Shell.FOIShellFolder, pidl, SHGDN_FORPARSING, &str)))
709     { if (SUCCEEDED(COMDLG32_StrRetToBufW(&str, pidl,szPathW, MAX_PATH)))
710       {
711           if (COMDLG32_PathMatchSpecW(szPathW, fodInfos->ShellInfos.lpstrCurrentFilter))
712           return S_OK;
713       }
714     }
715     return S_FALSE;
716
717 }
718
719 /**************************************************************************
720 *  IShellBrowserImpl_ICommDlgBrowser_OnSelChange
721 */  
722 HRESULT IShellBrowserImpl_ICommDlgBrowser_OnSelChange(ICommDlgBrowser *iface, IShellView *ppshv)
723 {
724     LPITEMIDLIST pidl;
725     FileOpenDlgInfos *fodInfos;
726     _ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
727
728     fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
729     TRACE("(%p)\n", This);
730
731     if((pidl = GetSelectedPidl(ppshv)))
732     {
733         HRESULT hRes = E_FAIL;
734         char lpstrFileName[MAX_PATH];
735     
736         ULONG  ulAttr = SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
737         IShellFolder_GetAttributesOf(fodInfos->Shell.FOIShellFolder, 1, &pidl, &ulAttr);
738         if (!ulAttr)
739         {
740             if(SUCCEEDED(hRes = GetName(fodInfos->Shell.FOIShellFolder,pidl,SHGDN_NORMAL,lpstrFileName)))
741                 SetWindowTextA(fodInfos->DlgInfos.hwndFileName,lpstrFileName);
742             if(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
743                     SetDlgItemTextA(fodInfos->ShellInfos.hwndOwner,IDOK,"&Save");
744         }
745         else
746             SetDlgItemTextA(fodInfos->ShellInfos.hwndOwner,IDOK,"&Open");
747
748         fodInfos->DlgInfos.dwDlgProp |= FODPROP_USEVIEW;
749
750         COMDLG32_SHFree((LPVOID)pidl);
751         return hRes;
752     }
753     if(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
754         SetDlgItemTextA(fodInfos->ShellInfos.hwndOwner,IDOK,"&Save");
755
756     fodInfos->DlgInfos.dwDlgProp &= ~FODPROP_USEVIEW;
757     return E_FAIL;
758 }
759
760 /***********************************************************************
761  *          GetSelectedPidl
762  *
763  * Return the pidl of the first selected item in the view
764  */
765 LPITEMIDLIST GetSelectedPidl(IShellView *ppshv)
766 {
767
768     IDataObject *doSelected;
769     LPITEMIDLIST pidlSelected = NULL;
770
771     TRACE("sv=%p\n", ppshv);
772
773     /* Get an IDataObject from the view */
774     if(SUCCEEDED(IShellView_GetItemObject(ppshv,
775                                           SVGIO_SELECTION,
776                                           &IID_IDataObject,
777                                           (LPVOID *)&doSelected)))
778     {
779         STGMEDIUM medium;
780         FORMATETC formatetc;
781         
782         /* Set the FORMATETC structure*/
783         SETDefFormatEtc(formatetc,
784                         RegisterClipboardFormatA(CFSTR_SHELLIDLIST),
785                         TYMED_HGLOBAL);
786
787         /* Get the pidl from IDataObject */
788         if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
789         {
790             LPIDA cida = GlobalLock(medium.u.hGlobal);
791             TRACE("cida=%p\n", cida);
792             pidlSelected =  COMDLG32_PIDL_ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[1]]));
793
794             if(medium.pUnkForRelease)
795                 IUnknown_Release(medium.pUnkForRelease);
796             else
797             {
798               GlobalUnlock(medium.u.hGlobal);
799               GlobalFree(medium.u.hGlobal);
800             }
801         }
802         IDataObject_Release(doSelected);
803         return pidlSelected;
804     }
805
806     return NULL;
807 }
808
809
810
811
812