1*96c0f7d3SMark Jansen /*
2*96c0f7d3SMark Jansen  * PROJECT:     ReactOS API tests
3*96c0f7d3SMark Jansen  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4*96c0f7d3SMark Jansen  * PURPOSE:     Test for IShellFolderViewCB
5*96c0f7d3SMark Jansen  * COPYRIGHT:   Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
6*96c0f7d3SMark Jansen  */
7*96c0f7d3SMark Jansen 
8*96c0f7d3SMark Jansen #include "shelltest.h"
9*96c0f7d3SMark Jansen #include <atlsimpcoll.h>
10*96c0f7d3SMark Jansen #include <stdio.h>
11*96c0f7d3SMark Jansen 
12*96c0f7d3SMark Jansen #if 1
13*96c0f7d3SMark Jansen #define DbgPrint(...)   trace(__VA_ARGS__)
14*96c0f7d3SMark Jansen #else
15*96c0f7d3SMark Jansen EXTERN_C
16*96c0f7d3SMark Jansen void DbgPrint(PCSTR, ...);
17*96c0f7d3SMark Jansen #endif
18*96c0f7d3SMark Jansen #include <shellutils.h>
19*96c0f7d3SMark Jansen //#include <msgtrace.h>
20*96c0f7d3SMark Jansen 
21*96c0f7d3SMark Jansen static DWORD g_WinVersion;
22*96c0f7d3SMark Jansen #define WINVER_VISTA   0x0600
23*96c0f7d3SMark Jansen 
24*96c0f7d3SMark Jansen #ifndef SFVM_SELECTIONCHANGED
25*96c0f7d3SMark Jansen #define SFVM_SELECTIONCHANGED          8 /* undocumented */
26*96c0f7d3SMark Jansen #define SFVM_DRAWMENUITEM              9 /* undocumented */
27*96c0f7d3SMark Jansen #define SFVM_MEASUREMENUITEM          10 /* undocumented */
28*96c0f7d3SMark Jansen #define SFVM_EXITMENULOOP             11 /* undocumented */
29*96c0f7d3SMark Jansen #define SFVM_VIEWRELEASE              12 /* undocumented */
30*96c0f7d3SMark Jansen #define SFVM_GETNAMELENGTH            13 /* undocumented */
31*96c0f7d3SMark Jansen #define SFVM_WINDOWCLOSING            16 /* undocumented */
32*96c0f7d3SMark Jansen #define SFVM_LISTREFRESHED            17 /* undocumented */
33*96c0f7d3SMark Jansen #define SFVM_WINDOWFOCUSED            18 /* undocumented */
34*96c0f7d3SMark Jansen #define SFVM_REGISTERCOPYHOOK         20 /* undocumented */
35*96c0f7d3SMark Jansen #define SFVM_COPYHOOKCALLBACK         21 /* undocumented */
36*96c0f7d3SMark Jansen #define SFVM_UNMERGEFROMMENU          28 /* undocumented */
37*96c0f7d3SMark Jansen #define SFVM_ADDINGOBJECT             29 /* undocumented */
38*96c0f7d3SMark Jansen #define SFVM_REMOVINGOBJECT           30 /* undocumented */
39*96c0f7d3SMark Jansen #define SFVM_GETCOMMANDDIR            33 /* undocumented */
40*96c0f7d3SMark Jansen #define SFVM_GETCOLUMNSTREAM          34 /* undocumented */
41*96c0f7d3SMark Jansen #define SFVM_CANSELECTALL             35 /* undocumented */
42*96c0f7d3SMark Jansen #define SFVM_ISSTRICTREFRESH          37 /* undocumented */
43*96c0f7d3SMark Jansen #define SFVM_ISCHILDOBJECT            38 /* undocumented */
44*96c0f7d3SMark Jansen #define SFVM_GETEXTVIEWS              40 /* undocumented */
45*96c0f7d3SMark Jansen #define SFVM_GET_CUSTOMVIEWINFO       77 /* undocumented */
46*96c0f7d3SMark Jansen #define SFVM_ENUMERATEDITEMS          79 /* undocumented */
47*96c0f7d3SMark Jansen #define SFVM_GET_VIEW_DATA            80 /* undocumented */
48*96c0f7d3SMark Jansen #define SFVM_GET_WEBVIEW_LAYOUT       82 /* undocumented */
49*96c0f7d3SMark Jansen #define SFVM_GET_WEBVIEW_CONTENT      83 /* undocumented */
50*96c0f7d3SMark Jansen #define SFVM_GET_WEBVIEW_TASKS        84 /* undocumented */
51*96c0f7d3SMark Jansen #define SFVM_GET_WEBVIEW_THEME        86 /* undocumented */
52*96c0f7d3SMark Jansen #define SFVM_GETDEFERREDVIEWSETTINGS  92 /* undocumented */
53*96c0f7d3SMark Jansen #endif
54*96c0f7d3SMark Jansen 
55*96c0f7d3SMark Jansen #define DUM_MSG_GetWindow               400
56*96c0f7d3SMark Jansen #define DUM_MSG_ContextSensitiveHelp    401
57*96c0f7d3SMark Jansen #define DUM_MSG_InsertMenusSB           402
58*96c0f7d3SMark Jansen #define DUM_MSG_SetMenuSB               403
59*96c0f7d3SMark Jansen #define DUM_MSG_RemoveMenusSB           404
60*96c0f7d3SMark Jansen #define DUM_MSG_SetStatusTextSB         405
61*96c0f7d3SMark Jansen #define DUM_MSG_EnableModelessSB        406
62*96c0f7d3SMark Jansen #define DUM_MSG_TranslateAcceleratorSB  407
63*96c0f7d3SMark Jansen #define DUM_MSG_BrowseObject            408
64*96c0f7d3SMark Jansen #define DUM_MSG_GetViewStateStream      409
65*96c0f7d3SMark Jansen #define DUM_MSG_GetControlWindow        410
66*96c0f7d3SMark Jansen #define DUM_MSG_SendControlMsg          411
67*96c0f7d3SMark Jansen #define DUM_MSG_QueryActiveShellView    412
68*96c0f7d3SMark Jansen #define DUM_MSG_OnViewWindowActive      413
69*96c0f7d3SMark Jansen #define DUM_MSG_SetToolbarItems         414
70*96c0f7d3SMark Jansen 
71*96c0f7d3SMark Jansen 
72*96c0f7d3SMark Jansen const char* msg2str(UINT uMsg)
73*96c0f7d3SMark Jansen {
74*96c0f7d3SMark Jansen     static char buf[2][50];
75*96c0f7d3SMark Jansen     static int index = 0;
76*96c0f7d3SMark Jansen     index ^= 1;
77*96c0f7d3SMark Jansen 
78*96c0f7d3SMark Jansen     switch (uMsg)
79*96c0f7d3SMark Jansen     {
80*96c0f7d3SMark Jansen     case SFVM_MERGEMENU: return "SFVM_MERGEMENU";
81*96c0f7d3SMark Jansen     case SFVM_INVOKECOMMAND: return "SFVM_INVOKECOMMAND";
82*96c0f7d3SMark Jansen     case SFVM_GETHELPTEXT: return "SFVM_GETHELPTEXT";
83*96c0f7d3SMark Jansen     case SFVM_GETTOOLTIPTEXT: return "SFVM_GETTOOLTIPTEXT";
84*96c0f7d3SMark Jansen     case SFVM_GETBUTTONINFO: return "SFVM_GETBUTTONINFO";
85*96c0f7d3SMark Jansen     case SFVM_GETBUTTONS: return "SFVM_GETBUTTONS";
86*96c0f7d3SMark Jansen     case SFVM_INITMENUPOPUP: return "SFVM_INITMENUPOPUP";
87*96c0f7d3SMark Jansen     case SFVM_SELECTIONCHANGED: return "SFVM_SELECTIONCHANGED";
88*96c0f7d3SMark Jansen     case SFVM_DRAWMENUITEM: return "SFVM_DRAWMENUITEM";
89*96c0f7d3SMark Jansen     case SFVM_MEASUREMENUITEM: return "SFVM_MEASUREMENUITEM";
90*96c0f7d3SMark Jansen     case SFVM_EXITMENULOOP: return "SFVM_EXITMENULOOP";
91*96c0f7d3SMark Jansen     case SFVM_VIEWRELEASE: return "SFVM_VIEWRELEASE";
92*96c0f7d3SMark Jansen     case SFVM_GETNAMELENGTH: return "SFVM_GETNAMELENGTH";
93*96c0f7d3SMark Jansen     case SFVM_FSNOTIFY: return "SFVM_FSNOTIFY";
94*96c0f7d3SMark Jansen     case SFVM_WINDOWCREATED: return "SFVM_WINDOWCREATED";
95*96c0f7d3SMark Jansen     case SFVM_WINDOWCLOSING: return "SFVM_WINDOWCLOSING";
96*96c0f7d3SMark Jansen     case SFVM_LISTREFRESHED: return "SFVM_LISTREFRESHED";
97*96c0f7d3SMark Jansen     case SFVM_WINDOWFOCUSED: return "SFVM_WINDOWFOCUSED";
98*96c0f7d3SMark Jansen     case SFVM_REGISTERCOPYHOOK: return "SFVM_REGISTERCOPYHOOK";
99*96c0f7d3SMark Jansen     case SFVM_COPYHOOKCALLBACK: return "SFVM_COPYHOOKCALLBACK";
100*96c0f7d3SMark Jansen     case SFVM_GETDETAILSOF: return "SFVM_GETDETAILSOF";
101*96c0f7d3SMark Jansen     case SFVM_COLUMNCLICK: return "SFVM_COLUMNCLICK";
102*96c0f7d3SMark Jansen     case SFVM_QUERYFSNOTIFY: return "SFVM_QUERYFSNOTIFY";
103*96c0f7d3SMark Jansen     case SFVM_DEFITEMCOUNT: return "SFVM_DEFITEMCOUNT";
104*96c0f7d3SMark Jansen     case SFVM_DEFVIEWMODE: return "SFVM_DEFVIEWMODE";
105*96c0f7d3SMark Jansen     case SFVM_UNMERGEFROMMENU: return "SFVM_UNMERGEFROMMENU";
106*96c0f7d3SMark Jansen     case SFVM_ADDINGOBJECT: return "SFVM_ADDINGOBJECT";
107*96c0f7d3SMark Jansen     case SFVM_REMOVINGOBJECT: return "SFVM_REMOVINGOBJECT";
108*96c0f7d3SMark Jansen     case SFVM_UPDATESTATUSBAR: return "SFVM_UPDATESTATUSBAR";
109*96c0f7d3SMark Jansen     case SFVM_BACKGROUNDENUM: return "SFVM_BACKGROUNDENUM";
110*96c0f7d3SMark Jansen     case SFVM_GETCOMMANDDIR: return "SFVM_GETCOMMANDDIR";
111*96c0f7d3SMark Jansen     case SFVM_GETCOLUMNSTREAM: return "SFVM_GETCOLUMNSTREAM";
112*96c0f7d3SMark Jansen     case SFVM_CANSELECTALL: return "SFVM_CANSELECTALL";
113*96c0f7d3SMark Jansen     case SFVM_DIDDRAGDROP: return "SFVM_DIDDRAGDROP";
114*96c0f7d3SMark Jansen     case SFVM_ISSTRICTREFRESH: return "SFVM_ISSTRICTREFRESH";
115*96c0f7d3SMark Jansen     case SFVM_ISCHILDOBJECT: return "SFVM_ISCHILDOBJECT";
116*96c0f7d3SMark Jansen     case SFVM_SETISFV: return "SFVM_SETISFV";
117*96c0f7d3SMark Jansen     case SFVM_GETEXTVIEWS: return "SFVM_GETEXTVIEWS";
118*96c0f7d3SMark Jansen     case SFVM_THISIDLIST: return "SFVM_THISIDLIST";
119*96c0f7d3SMark Jansen     case SFVM_ADDPROPERTYPAGES: return "SFVM_ADDPROPERTYPAGES";
120*96c0f7d3SMark Jansen     case SFVM_BACKGROUNDENUMDONE: return "SFVM_BACKGROUNDENUMDONE";
121*96c0f7d3SMark Jansen     case SFVM_GETNOTIFY: return "SFVM_GETNOTIFY";
122*96c0f7d3SMark Jansen     case SFVM_GETSORTDEFAULTS: return "SFVM_GETSORTDEFAULTS";
123*96c0f7d3SMark Jansen     case SFVM_SIZE: return "SFVM_SIZE";
124*96c0f7d3SMark Jansen     case SFVM_GETZONE: return "SFVM_GETZONE";
125*96c0f7d3SMark Jansen     case SFVM_GETPANE: return "SFVM_GETPANE";
126*96c0f7d3SMark Jansen     case SFVM_GETHELPTOPIC: return "SFVM_GETHELPTOPIC";
127*96c0f7d3SMark Jansen     case SFVM_GETANIMATION: return "SFVM_GETANIMATION";
128*96c0f7d3SMark Jansen     case SFVM_GET_CUSTOMVIEWINFO: return "SFVM_GET_CUSTOMVIEWINFO";
129*96c0f7d3SMark Jansen     case SFVM_ENUMERATEDITEMS: return "SFVM_ENUMERATEDITEMS";
130*96c0f7d3SMark Jansen     case SFVM_GET_VIEW_DATA: return "SFVM_GET_VIEW_DATA";
131*96c0f7d3SMark Jansen     case SFVM_GET_WEBVIEW_LAYOUT: return "SFVM_GET_WEBVIEW_LAYOUT";
132*96c0f7d3SMark Jansen     case SFVM_GET_WEBVIEW_CONTENT: return "SFVM_GET_WEBVIEW_CONTENT";
133*96c0f7d3SMark Jansen     case SFVM_GET_WEBVIEW_TASKS: return "SFVM_GET_WEBVIEW_TASKS";
134*96c0f7d3SMark Jansen     case SFVM_GET_WEBVIEW_THEME: return "SFVM_GET_WEBVIEW_THEME";
135*96c0f7d3SMark Jansen     case SFVM_GETDEFERREDVIEWSETTINGS: return "SFVM_GET_WEBVIEW_THEME";
136*96c0f7d3SMark Jansen 
137*96c0f7d3SMark Jansen     case DUM_MSG_GetWindow: return "|GetWindow|";
138*96c0f7d3SMark Jansen     case DUM_MSG_ContextSensitiveHelp: return "|ContextSensitiveHelp|";
139*96c0f7d3SMark Jansen     case DUM_MSG_InsertMenusSB: return "|InsertMenusSB|";
140*96c0f7d3SMark Jansen     case DUM_MSG_SetMenuSB: return "|SetMenuSB|";
141*96c0f7d3SMark Jansen     case DUM_MSG_RemoveMenusSB: return "|RemoveMenusSB|";
142*96c0f7d3SMark Jansen     case DUM_MSG_SetStatusTextSB: return "|SetStatusTextSB|";
143*96c0f7d3SMark Jansen     case DUM_MSG_EnableModelessSB: return "|EnableModelessSB|";
144*96c0f7d3SMark Jansen     case DUM_MSG_TranslateAcceleratorSB: return "|TranslateAcceleratorSB|";
145*96c0f7d3SMark Jansen     case DUM_MSG_BrowseObject: return "|BrowseObject|";
146*96c0f7d3SMark Jansen     case DUM_MSG_GetViewStateStream: return "|GetViewStateStream|";
147*96c0f7d3SMark Jansen     case DUM_MSG_GetControlWindow: return "|GetControlWindow|";
148*96c0f7d3SMark Jansen     case DUM_MSG_SendControlMsg: return "|SendControlMsg|";
149*96c0f7d3SMark Jansen     case DUM_MSG_QueryActiveShellView: return "|QueryActiveShellView|";
150*96c0f7d3SMark Jansen     case DUM_MSG_OnViewWindowActive: return "|OnViewWindowActive|";
151*96c0f7d3SMark Jansen     case DUM_MSG_SetToolbarItems: return "|SetToolbarItems|";
152*96c0f7d3SMark Jansen     default:
153*96c0f7d3SMark Jansen         sprintf(buf[index], "[%u]", uMsg);
154*96c0f7d3SMark Jansen         return buf[index];
155*96c0f7d3SMark Jansen     }
156*96c0f7d3SMark Jansen }
157*96c0f7d3SMark Jansen 
158*96c0f7d3SMark Jansen 
159*96c0f7d3SMark Jansen #define PTR_VALUE   0xf7f7f7f7
160*96c0f7d3SMark Jansen 
161*96c0f7d3SMark Jansen struct message
162*96c0f7d3SMark Jansen {
163*96c0f7d3SMark Jansen     message(UINT msg, WPARAM wp, LPARAM lp) : uMsg(msg), wParam(wp), lParam(lp) { ; }
164*96c0f7d3SMark Jansen 
165*96c0f7d3SMark Jansen     UINT uMsg;
166*96c0f7d3SMark Jansen     WPARAM wParam;
167*96c0f7d3SMark Jansen     LPARAM lParam;
168*96c0f7d3SMark Jansen };
169*96c0f7d3SMark Jansen 
170*96c0f7d3SMark Jansen CSimpleArray<message> g_Received;
171*96c0f7d3SMark Jansen 
172*96c0f7d3SMark Jansen void clear_list()
173*96c0f7d3SMark Jansen {
174*96c0f7d3SMark Jansen     g_Received.RemoveAll();
175*96c0f7d3SMark Jansen }
176*96c0f7d3SMark Jansen 
177*96c0f7d3SMark Jansen void add_msg(UINT uMsg, WPARAM wParam, LPARAM lParam)
178*96c0f7d3SMark Jansen {
179*96c0f7d3SMark Jansen     g_Received.Add(message(uMsg, wParam, lParam));
180*96c0f7d3SMark Jansen }
181*96c0f7d3SMark Jansen 
182*96c0f7d3SMark Jansen void print_list_(const CSimpleArray<message>& input, const char* file, int line)
183*96c0f7d3SMark Jansen {
184*96c0f7d3SMark Jansen     trace_(file, line)("Got list:\n");
185*96c0f7d3SMark Jansen     for (int n = 0; n < input.GetSize(); ++n)
186*96c0f7d3SMark Jansen     {
187*96c0f7d3SMark Jansen         const message& msg = input[n];
188*96c0f7d3SMark Jansen         trace_(file, line)("msg: %d(%s), wParam:0x%x, lParam:0x%lx\n", msg.uMsg, msg2str(msg.uMsg), msg.wParam, msg.lParam);
189*96c0f7d3SMark Jansen     }
190*96c0f7d3SMark Jansen     trace_(file, line)("End of list.\n");
191*96c0f7d3SMark Jansen }
192*96c0f7d3SMark Jansen 
193*96c0f7d3SMark Jansen void compare_list_(const CSimpleArray<message>& input, const message* compare, const char* file, int line)
194*96c0f7d3SMark Jansen {
195*96c0f7d3SMark Jansen     int input_item = 0;
196*96c0f7d3SMark Jansen     int compare_item = 0;
197*96c0f7d3SMark Jansen     LONG old_failures = winetest_get_failures();
198*96c0f7d3SMark Jansen     while (compare[compare_item].uMsg && input_item < input.GetSize())
199*96c0f7d3SMark Jansen     {
200*96c0f7d3SMark Jansen         const message& inp = input[input_item];
201*96c0f7d3SMark Jansen         const message& cmp = compare[compare_item];
202*96c0f7d3SMark Jansen         if (cmp.uMsg == inp.uMsg)
203*96c0f7d3SMark Jansen         {
204*96c0f7d3SMark Jansen             if (cmp.lParam != (LPARAM)PTR_VALUE)
205*96c0f7d3SMark Jansen             {
206*96c0f7d3SMark Jansen                 ok_(file, line)(cmp.lParam == inp.lParam, "Expected lParam to be 0x%lx, was 0x%lx for %i(%s)\n",
207*96c0f7d3SMark Jansen                                 cmp.lParam, inp.lParam, compare_item, msg2str(cmp.uMsg));
208*96c0f7d3SMark Jansen             }
209*96c0f7d3SMark Jansen             else
210*96c0f7d3SMark Jansen             {
211*96c0f7d3SMark Jansen                 ok_(file, line)(inp.lParam != 0, "Expected lParam to be a pointer, was 0 for %i(%s)\n",
212*96c0f7d3SMark Jansen                                 compare_item, msg2str(cmp.uMsg));
213*96c0f7d3SMark Jansen             }
214*96c0f7d3SMark Jansen             if (cmp.wParam != PTR_VALUE)
215*96c0f7d3SMark Jansen             {
216*96c0f7d3SMark Jansen                 ok_(file, line)(cmp.wParam == inp.wParam, "Expected wParam to be 0x%x, was 0x%x for %i(%s)\n",
217*96c0f7d3SMark Jansen                                 cmp.wParam, inp.wParam, compare_item, msg2str(cmp.uMsg));
218*96c0f7d3SMark Jansen             }
219*96c0f7d3SMark Jansen             else
220*96c0f7d3SMark Jansen             {
221*96c0f7d3SMark Jansen                 ok_(file, line)(inp.wParam != 0, "Expected wParam to be a pointer, was 0 for %i(%s)\n",
222*96c0f7d3SMark Jansen                                 compare_item, msg2str(cmp.uMsg));
223*96c0f7d3SMark Jansen             }
224*96c0f7d3SMark Jansen             compare_item++;
225*96c0f7d3SMark Jansen         }
226*96c0f7d3SMark Jansen         else
227*96c0f7d3SMark Jansen         {
228*96c0f7d3SMark Jansen             /* We skip unknown items for now */
229*96c0f7d3SMark Jansen         }
230*96c0f7d3SMark Jansen 
231*96c0f7d3SMark Jansen         input_item++;
232*96c0f7d3SMark Jansen     }
233*96c0f7d3SMark Jansen 
234*96c0f7d3SMark Jansen     while (compare[compare_item].uMsg)
235*96c0f7d3SMark Jansen     {
236*96c0f7d3SMark Jansen         ok_(file, line)(0, "Message %i(%s) not found\n", compare_item, msg2str(compare[compare_item].uMsg));
237*96c0f7d3SMark Jansen         compare_item++;
238*96c0f7d3SMark Jansen     }
239*96c0f7d3SMark Jansen     if (old_failures != winetest_get_failures())
240*96c0f7d3SMark Jansen     {
241*96c0f7d3SMark Jansen         print_list_(input, file, line);
242*96c0f7d3SMark Jansen     }
243*96c0f7d3SMark Jansen }
244*96c0f7d3SMark Jansen 
245*96c0f7d3SMark Jansen #define compare_list(cmp)   compare_list_(g_Received, cmp, __FILE__, __LINE__)
246*96c0f7d3SMark Jansen #define print_list()        print_list_(g_Received, __FILE__, __LINE__)
247*96c0f7d3SMark Jansen 
248*96c0f7d3SMark Jansen 
249*96c0f7d3SMark Jansen LONG g_AddRef = 0;
250*96c0f7d3SMark Jansen LONG g_Release = 0;
251*96c0f7d3SMark Jansen 
252*96c0f7d3SMark Jansen class CFolderViewCB :
253*96c0f7d3SMark Jansen     public IShellFolderViewCB
254*96c0f7d3SMark Jansen {
255*96c0f7d3SMark Jansen public:
256*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void  **ppvObject)
257*96c0f7d3SMark Jansen     {
258*96c0f7d3SMark Jansen         if (riid == IID_IShellFolderViewCB || riid == IID_IUnknown)
259*96c0f7d3SMark Jansen         {
260*96c0f7d3SMark Jansen             *ppvObject = this;
261*96c0f7d3SMark Jansen             AddRef();
262*96c0f7d3SMark Jansen             return S_OK;
263*96c0f7d3SMark Jansen         }
264*96c0f7d3SMark Jansen         return E_NOINTERFACE;
265*96c0f7d3SMark Jansen     }
266*96c0f7d3SMark Jansen     virtual ULONG STDMETHODCALLTYPE AddRef(void)
267*96c0f7d3SMark Jansen     {
268*96c0f7d3SMark Jansen         InterlockedIncrement(&g_AddRef);
269*96c0f7d3SMark Jansen         return 2;
270*96c0f7d3SMark Jansen     }
271*96c0f7d3SMark Jansen     virtual ULONG STDMETHODCALLTYPE Release(void)
272*96c0f7d3SMark Jansen     {
273*96c0f7d3SMark Jansen         InterlockedIncrement(&g_Release);
274*96c0f7d3SMark Jansen         return 1;
275*96c0f7d3SMark Jansen     }
276*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
277*96c0f7d3SMark Jansen     {
278*96c0f7d3SMark Jansen         //DbgPrint("MessageSFVCB(uMsg:%s, wParam:%u, lParam:%u\n", msg2str(uMsg), wParam, lParam);
279*96c0f7d3SMark Jansen         add_msg(uMsg, wParam, lParam);
280*96c0f7d3SMark Jansen         return E_NOTIMPL;
281*96c0f7d3SMark Jansen     }
282*96c0f7d3SMark Jansen };
283*96c0f7d3SMark Jansen 
284*96c0f7d3SMark Jansen 
285*96c0f7d3SMark Jansen static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
286*96c0f7d3SMark Jansen {
287*96c0f7d3SMark Jansen     if (msg == WM_DESTROY)
288*96c0f7d3SMark Jansen     {
289*96c0f7d3SMark Jansen         PostQuitMessage(0);
290*96c0f7d3SMark Jansen         return 0;
291*96c0f7d3SMark Jansen     }
292*96c0f7d3SMark Jansen     return DefWindowProc(hwnd, msg, wParam, lParam);
293*96c0f7d3SMark Jansen }
294*96c0f7d3SMark Jansen 
295*96c0f7d3SMark Jansen 
296*96c0f7d3SMark Jansen class CDummyShellBrowser : public IShellBrowser
297*96c0f7d3SMark Jansen {
298*96c0f7d3SMark Jansen public:
299*96c0f7d3SMark Jansen     HWND m_hwnd;
300*96c0f7d3SMark Jansen     CDummyShellBrowser()
301*96c0f7d3SMark Jansen     {
302*96c0f7d3SMark Jansen         static const TCHAR* class_name = TEXT("DUMMY_TEST_CLASS");
303*96c0f7d3SMark Jansen         WNDCLASSEX wx = {};
304*96c0f7d3SMark Jansen         wx.cbSize = sizeof(WNDCLASSEX);
305*96c0f7d3SMark Jansen         wx.lpfnWndProc = WndProc;
306*96c0f7d3SMark Jansen         wx.hInstance = GetModuleHandle(NULL);
307*96c0f7d3SMark Jansen         wx.lpszClassName = class_name;
308*96c0f7d3SMark Jansen         wx.style = CS_DBLCLKS;
309*96c0f7d3SMark Jansen         RegisterClassEx(&wx);
310*96c0f7d3SMark Jansen         m_hwnd = CreateWindowEx(0, class_name, TEXT("dummy_name"), WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
311*96c0f7d3SMark Jansen         ShowWindow(m_hwnd, SW_SHOW);
312*96c0f7d3SMark Jansen     }
313*96c0f7d3SMark Jansen 
314*96c0f7d3SMark Jansen     // *** IUnknown methods ***
315*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void  **ppvObject)
316*96c0f7d3SMark Jansen     {
317*96c0f7d3SMark Jansen         if (riid == IID_IShellBrowser || riid == IID_IUnknown)
318*96c0f7d3SMark Jansen         {
319*96c0f7d3SMark Jansen             *ppvObject = this;
320*96c0f7d3SMark Jansen             return S_OK;
321*96c0f7d3SMark Jansen         }
322*96c0f7d3SMark Jansen         return E_NOINTERFACE;
323*96c0f7d3SMark Jansen     }
324*96c0f7d3SMark Jansen     virtual ULONG STDMETHODCALLTYPE AddRef(void)
325*96c0f7d3SMark Jansen     {
326*96c0f7d3SMark Jansen         return 2;
327*96c0f7d3SMark Jansen     }
328*96c0f7d3SMark Jansen     virtual ULONG STDMETHODCALLTYPE Release(void)
329*96c0f7d3SMark Jansen     {
330*96c0f7d3SMark Jansen         return 1;
331*96c0f7d3SMark Jansen     }
332*96c0f7d3SMark Jansen 
333*96c0f7d3SMark Jansen     // *** IOleWindow methods ***
334*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd)
335*96c0f7d3SMark Jansen     {
336*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
337*96c0f7d3SMark Jansen         *phwnd = m_hwnd;
338*96c0f7d3SMark Jansen         add_msg(DUM_MSG_GetWindow, NULL, NULL);
339*96c0f7d3SMark Jansen         return S_OK;
340*96c0f7d3SMark Jansen     }
341*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode)
342*96c0f7d3SMark Jansen     {
343*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
344*96c0f7d3SMark Jansen         add_msg(DUM_MSG_ContextSensitiveHelp, NULL, NULL);
345*96c0f7d3SMark Jansen         return E_NOTIMPL;
346*96c0f7d3SMark Jansen     }
347*96c0f7d3SMark Jansen 
348*96c0f7d3SMark Jansen     // *** IShellBrowser methods ***
349*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
350*96c0f7d3SMark Jansen     {
351*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
352*96c0f7d3SMark Jansen         add_msg(DUM_MSG_InsertMenusSB, NULL, NULL);
353*96c0f7d3SMark Jansen         return S_OK;
354*96c0f7d3SMark Jansen     }
355*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject)
356*96c0f7d3SMark Jansen     {
357*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
358*96c0f7d3SMark Jansen         add_msg(DUM_MSG_SetMenuSB, NULL, NULL);
359*96c0f7d3SMark Jansen         return S_OK;
360*96c0f7d3SMark Jansen     }
361*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE RemoveMenusSB(HMENU hmenuShared)
362*96c0f7d3SMark Jansen     {
363*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
364*96c0f7d3SMark Jansen         add_msg(DUM_MSG_RemoveMenusSB, NULL, NULL);
365*96c0f7d3SMark Jansen         return E_NOTIMPL;
366*96c0f7d3SMark Jansen     }
367*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE SetStatusTextSB(LPCWSTR pszStatusText)
368*96c0f7d3SMark Jansen     {
369*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
370*96c0f7d3SMark Jansen         add_msg(DUM_MSG_SetStatusTextSB, NULL, NULL);
371*96c0f7d3SMark Jansen         return E_NOTIMPL;
372*96c0f7d3SMark Jansen     }
373*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE EnableModelessSB(BOOL fEnable)
374*96c0f7d3SMark Jansen     {
375*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
376*96c0f7d3SMark Jansen         add_msg(DUM_MSG_EnableModelessSB, NULL, NULL);
377*96c0f7d3SMark Jansen         return E_NOTIMPL;
378*96c0f7d3SMark Jansen     }
379*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorSB(MSG *pmsg, WORD wID)
380*96c0f7d3SMark Jansen     {
381*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
382*96c0f7d3SMark Jansen         add_msg(DUM_MSG_TranslateAcceleratorSB, NULL, NULL);
383*96c0f7d3SMark Jansen         return E_NOTIMPL;
384*96c0f7d3SMark Jansen     }
385*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE BrowseObject(PCUIDLIST_RELATIVE pidl,UINT wFlags)
386*96c0f7d3SMark Jansen     {
387*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
388*96c0f7d3SMark Jansen         add_msg(DUM_MSG_BrowseObject, NULL, NULL);
389*96c0f7d3SMark Jansen         return E_NOTIMPL;
390*96c0f7d3SMark Jansen     }
391*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE GetViewStateStream(DWORD grfMode,IStream **ppStrm)
392*96c0f7d3SMark Jansen     {
393*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
394*96c0f7d3SMark Jansen         add_msg(DUM_MSG_GetViewStateStream, NULL, NULL);
395*96c0f7d3SMark Jansen         return E_NOTIMPL;
396*96c0f7d3SMark Jansen     }
397*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE GetControlWindow(UINT id,HWND *phwnd)
398*96c0f7d3SMark Jansen     {
399*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
400*96c0f7d3SMark Jansen         add_msg(DUM_MSG_GetControlWindow, NULL, NULL);
401*96c0f7d3SMark Jansen         return E_NOTIMPL;
402*96c0f7d3SMark Jansen     }
403*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE SendControlMsg(UINT id,UINT uMsg,WPARAM wParam,LPARAM lParam,LRESULT *pret)
404*96c0f7d3SMark Jansen     {
405*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
406*96c0f7d3SMark Jansen         add_msg(DUM_MSG_SendControlMsg, NULL, NULL);
407*96c0f7d3SMark Jansen         return E_NOTIMPL;
408*96c0f7d3SMark Jansen     }
409*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE QueryActiveShellView(IShellView **ppshv)
410*96c0f7d3SMark Jansen     {
411*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
412*96c0f7d3SMark Jansen         add_msg(DUM_MSG_QueryActiveShellView, NULL, NULL);
413*96c0f7d3SMark Jansen         return E_NOTIMPL;
414*96c0f7d3SMark Jansen     }
415*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE OnViewWindowActive(IShellView *pshv)
416*96c0f7d3SMark Jansen     {
417*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
418*96c0f7d3SMark Jansen         add_msg(DUM_MSG_OnViewWindowActive, NULL, NULL);
419*96c0f7d3SMark Jansen         return E_NOTIMPL;
420*96c0f7d3SMark Jansen     }
421*96c0f7d3SMark Jansen     virtual HRESULT STDMETHODCALLTYPE SetToolbarItems(LPTBBUTTONSB lpButtons,UINT nButtons,UINT uFlags)
422*96c0f7d3SMark Jansen     {
423*96c0f7d3SMark Jansen         //DbgPrint("%s()\n", __FUNCTION__);
424*96c0f7d3SMark Jansen         add_msg(DUM_MSG_SetToolbarItems, NULL, NULL);
425*96c0f7d3SMark Jansen         return E_NOTIMPL;
426*96c0f7d3SMark Jansen     }
427*96c0f7d3SMark Jansen };
428*96c0f7d3SMark Jansen 
429*96c0f7d3SMark Jansen 
430*96c0f7d3SMark Jansen START_TEST(IShellFolderViewCB)
431*96c0f7d3SMark Jansen {
432*96c0f7d3SMark Jansen     RTL_OSVERSIONINFOEXW rtlinfo = { sizeof(rtlinfo) };
433*96c0f7d3SMark Jansen     void (__stdcall* pRtlGetVersion)(RTL_OSVERSIONINFOEXW*);
434*96c0f7d3SMark Jansen     pRtlGetVersion = (void (__stdcall*)(RTL_OSVERSIONINFOEXW*))GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion");
435*96c0f7d3SMark Jansen     pRtlGetVersion(&rtlinfo);
436*96c0f7d3SMark Jansen     g_WinVersion = (rtlinfo.dwMajorVersion << 8) | rtlinfo.dwMinorVersion;
437*96c0f7d3SMark Jansen 
438*96c0f7d3SMark Jansen     CoInitialize(NULL);
439*96c0f7d3SMark Jansen     CFolderViewCB cb;
440*96c0f7d3SMark Jansen 
441*96c0f7d3SMark Jansen     CComPtr<IShellFolder> desktop;
442*96c0f7d3SMark Jansen 
443*96c0f7d3SMark Jansen     HRESULT hr = SHGetDesktopFolder(&desktop);
444*96c0f7d3SMark Jansen     ok_hex(hr, S_OK);
445*96c0f7d3SMark Jansen     if (!desktop)
446*96c0f7d3SMark Jansen         return;
447*96c0f7d3SMark Jansen 
448*96c0f7d3SMark Jansen     SFV_CREATE sfvc = { sizeof(sfvc), desktop };
449*96c0f7d3SMark Jansen     sfvc.psfvcb = &cb;
450*96c0f7d3SMark Jansen     IShellView* psv = NULL;
451*96c0f7d3SMark Jansen 
452*96c0f7d3SMark Jansen     g_AddRef = 0;
453*96c0f7d3SMark Jansen     g_Release = 0;
454*96c0f7d3SMark Jansen 
455*96c0f7d3SMark Jansen     hr = SHCreateShellFolderView(&sfvc, &psv);
456*96c0f7d3SMark Jansen     ok_hex(hr, S_OK);
457*96c0f7d3SMark Jansen     if (!SUCCEEDED(hr))
458*96c0f7d3SMark Jansen         return;
459*96c0f7d3SMark Jansen 
460*96c0f7d3SMark Jansen     ok_int(g_AddRef, 2);
461*96c0f7d3SMark Jansen     ok_int(g_Release, 0);
462*96c0f7d3SMark Jansen 
463*96c0f7d3SMark Jansen     clear_list();
464*96c0f7d3SMark Jansen 
465*96c0f7d3SMark Jansen     HWND wnd;
466*96c0f7d3SMark Jansen     RECT rc = { 0 };
467*96c0f7d3SMark Jansen     FOLDERSETTINGS fs = { FVM_DETAILS, 0 };
468*96c0f7d3SMark Jansen     CDummyShellBrowser dum;
469*96c0f7d3SMark Jansen     hr = psv->CreateViewWindow(NULL, &fs, &dum, &rc, &wnd);
470*96c0f7d3SMark Jansen 
471*96c0f7d3SMark Jansen 
472*96c0f7d3SMark Jansen     static message init_list[] =
473*96c0f7d3SMark Jansen     {
474*96c0f7d3SMark Jansen         /* ... */
475*96c0f7d3SMark Jansen         message(DUM_MSG_GetWindow, 0, 0),
476*96c0f7d3SMark Jansen         /* Some unknown messages here, and multiple SFVM_GET_WEBVIEW_THEME + SFVM_GETSORTDEFAULTS + SFVM_GETCOLUMNSTREAM */
477*96c0f7d3SMark Jansen         message(SFVM_SIZE, 0, 0),
478*96c0f7d3SMark Jansen         /* ... */
479*96c0f7d3SMark Jansen         message(DUM_MSG_InsertMenusSB, 0, 0),
480*96c0f7d3SMark Jansen         message(SFVM_MERGEMENU, 0, PTR_VALUE),
481*96c0f7d3SMark Jansen         message(DUM_MSG_SetMenuSB, 0, 0),
482*96c0f7d3SMark Jansen         /* ... */
483*96c0f7d3SMark Jansen         message(SFVM_WINDOWCREATED, PTR_VALUE, 0),
484*96c0f7d3SMark Jansen         /* ... */
485*96c0f7d3SMark Jansen 
486*96c0f7d3SMark Jansen         message(SFVM_GETBUTTONINFO, 0, PTR_VALUE),
487*96c0f7d3SMark Jansen         message(SFVM_GETBUTTONS, PTR_VALUE, PTR_VALUE),
488*96c0f7d3SMark Jansen         message(DUM_MSG_SetToolbarItems, 0, 0),
489*96c0f7d3SMark Jansen 
490*96c0f7d3SMark Jansen         message(0, 0, 0)
491*96c0f7d3SMark Jansen     };
492*96c0f7d3SMark Jansen 
493*96c0f7d3SMark Jansen 
494*96c0f7d3SMark Jansen     static message init_list_vista[] =
495*96c0f7d3SMark Jansen     {
496*96c0f7d3SMark Jansen         /* Some unknown messages here */
497*96c0f7d3SMark Jansen         message(DUM_MSG_GetWindow, 0, 0),
498*96c0f7d3SMark Jansen         /* Some unknown messages here, and multiple SFVM_GET_WEBVIEW_THEME + SFVM_GETSORTDEFAULTS + SFVM_GETCOLUMNSTREAM */
499*96c0f7d3SMark Jansen         message(SFVM_SIZE, 0, 0),
500*96c0f7d3SMark Jansen         message(SFVM_WINDOWCREATED, PTR_VALUE, 0),
501*96c0f7d3SMark Jansen         /* Some unknown messages here */
502*96c0f7d3SMark Jansen         message(DUM_MSG_InsertMenusSB, 0, 0),
503*96c0f7d3SMark Jansen         message(SFVM_MERGEMENU, 0, PTR_VALUE),
504*96c0f7d3SMark Jansen         message(DUM_MSG_SetMenuSB, 0, 0),
505*96c0f7d3SMark Jansen 
506*96c0f7d3SMark Jansen         message(0, 0, 0)
507*96c0f7d3SMark Jansen     };
508*96c0f7d3SMark Jansen 
509*96c0f7d3SMark Jansen     if (g_WinVersion < WINVER_VISTA)
510*96c0f7d3SMark Jansen     {
511*96c0f7d3SMark Jansen         compare_list(init_list);
512*96c0f7d3SMark Jansen     }
513*96c0f7d3SMark Jansen     else
514*96c0f7d3SMark Jansen     {
515*96c0f7d3SMark Jansen         compare_list(init_list_vista);
516*96c0f7d3SMark Jansen     }
517*96c0f7d3SMark Jansen     clear_list();
518*96c0f7d3SMark Jansen 
519*96c0f7d3SMark Jansen     hr = psv->Refresh();
520*96c0f7d3SMark Jansen     //ok_hex(hr, S_FALSE);
521*96c0f7d3SMark Jansen 
522*96c0f7d3SMark Jansen     static message refresh_list[] =
523*96c0f7d3SMark Jansen     {
524*96c0f7d3SMark Jansen         message(SFVM_LISTREFRESHED, 1, 0),
525*96c0f7d3SMark Jansen 
526*96c0f7d3SMark Jansen         message(SFVM_UNMERGEFROMMENU, 0, PTR_VALUE),
527*96c0f7d3SMark Jansen         message(DUM_MSG_SetMenuSB, 0, 0),
528*96c0f7d3SMark Jansen         message(DUM_MSG_RemoveMenusSB, 0, 0),
529*96c0f7d3SMark Jansen         message(DUM_MSG_InsertMenusSB, 0, 0),
530*96c0f7d3SMark Jansen         message(SFVM_MERGEMENU, 0, PTR_VALUE),
531*96c0f7d3SMark Jansen         message(DUM_MSG_SetMenuSB, 0, 0),
532*96c0f7d3SMark Jansen 
533*96c0f7d3SMark Jansen         message(0, 0, 0)
534*96c0f7d3SMark Jansen     };
535*96c0f7d3SMark Jansen 
536*96c0f7d3SMark Jansen     static message refresh_list_vista[] =
537*96c0f7d3SMark Jansen     {
538*96c0f7d3SMark Jansen         message(SFVM_LISTREFRESHED, 1, 0),
539*96c0f7d3SMark Jansen 
540*96c0f7d3SMark Jansen         message(SFVM_UNMERGEFROMMENU, 0, PTR_VALUE),
541*96c0f7d3SMark Jansen         message(DUM_MSG_SetMenuSB, 0, 0),
542*96c0f7d3SMark Jansen         message(DUM_MSG_RemoveMenusSB, 0, 0),
543*96c0f7d3SMark Jansen         message(DUM_MSG_InsertMenusSB, 0, 0),
544*96c0f7d3SMark Jansen         message(SFVM_MERGEMENU, 0, PTR_VALUE),
545*96c0f7d3SMark Jansen         message(DUM_MSG_SetMenuSB, 0, 0),
546*96c0f7d3SMark Jansen         /* Some messages here, like SFVM_GET_WEBVIEW_THEME, SFVM_GETSORTDEFAULTS, SFVM_GETCOLUMNSTREAM */
547*96c0f7d3SMark Jansen         message(SFVM_UNMERGEFROMMENU, 0, PTR_VALUE),
548*96c0f7d3SMark Jansen         message(DUM_MSG_SetMenuSB, 0, 0),
549*96c0f7d3SMark Jansen         message(DUM_MSG_RemoveMenusSB, 0, 0),
550*96c0f7d3SMark Jansen         message(DUM_MSG_InsertMenusSB, 0, 0),
551*96c0f7d3SMark Jansen         message(SFVM_MERGEMENU, 0, PTR_VALUE),
552*96c0f7d3SMark Jansen         message(DUM_MSG_SetMenuSB, 0, 0),
553*96c0f7d3SMark Jansen 
554*96c0f7d3SMark Jansen         message(0, 0, 0)
555*96c0f7d3SMark Jansen     };
556*96c0f7d3SMark Jansen 
557*96c0f7d3SMark Jansen     if (g_WinVersion < WINVER_VISTA)
558*96c0f7d3SMark Jansen     {
559*96c0f7d3SMark Jansen         compare_list(refresh_list);
560*96c0f7d3SMark Jansen     }
561*96c0f7d3SMark Jansen     else
562*96c0f7d3SMark Jansen     {
563*96c0f7d3SMark Jansen         compare_list(refresh_list_vista);
564*96c0f7d3SMark Jansen     }
565*96c0f7d3SMark Jansen     clear_list();
566*96c0f7d3SMark Jansen 
567*96c0f7d3SMark Jansen     hr = psv->DestroyViewWindow();
568*96c0f7d3SMark Jansen 
569*96c0f7d3SMark Jansen     static message destroy_list[] =
570*96c0f7d3SMark Jansen     {
571*96c0f7d3SMark Jansen         message(SFVM_UNMERGEFROMMENU, 0, PTR_VALUE),
572*96c0f7d3SMark Jansen         message(DUM_MSG_SetMenuSB, 0, 0),
573*96c0f7d3SMark Jansen         message(DUM_MSG_RemoveMenusSB, 0, 0),
574*96c0f7d3SMark Jansen         message(SFVM_WINDOWCLOSING, PTR_VALUE, 0),
575*96c0f7d3SMark Jansen 
576*96c0f7d3SMark Jansen         message(0, 0, 0)
577*96c0f7d3SMark Jansen     };
578*96c0f7d3SMark Jansen 
579*96c0f7d3SMark Jansen     compare_list(destroy_list);
580*96c0f7d3SMark Jansen     clear_list();
581*96c0f7d3SMark Jansen 
582*96c0f7d3SMark Jansen     CComPtr<IShellFolderView> folderView;
583*96c0f7d3SMark Jansen     hr = psv->QueryInterface(IID_PPV_ARG(IShellFolderView, &folderView));
584*96c0f7d3SMark Jansen     ok_hex(hr, S_OK);
585*96c0f7d3SMark Jansen     if (SUCCEEDED(hr))
586*96c0f7d3SMark Jansen     {
587*96c0f7d3SMark Jansen         IShellFolderViewCB* oldPtr;
588*96c0f7d3SMark Jansen 
589*96c0f7d3SMark Jansen         g_AddRef = 0;
590*96c0f7d3SMark Jansen         g_Release = 0;
591*96c0f7d3SMark Jansen 
592*96c0f7d3SMark Jansen         hr = folderView->SetCallback(NULL, &oldPtr);
593*96c0f7d3SMark Jansen         ok_int(g_AddRef, 0);
594*96c0f7d3SMark Jansen         ok_int(g_Release, 0);
595*96c0f7d3SMark Jansen 
596*96c0f7d3SMark Jansen         g_AddRef = 0;
597*96c0f7d3SMark Jansen         g_Release = 0;
598*96c0f7d3SMark Jansen 
599*96c0f7d3SMark Jansen         /* Last pointer is not optional! */
600*96c0f7d3SMark Jansen         IShellFolderViewCB* oldPtr2;
601*96c0f7d3SMark Jansen         hr = folderView->SetCallback(oldPtr, &oldPtr2);
602*96c0f7d3SMark Jansen         ok_int(g_AddRef, 1);
603*96c0f7d3SMark Jansen         ok_int(g_Release, 0);
604*96c0f7d3SMark Jansen     }
605*96c0f7d3SMark Jansen 
606*96c0f7d3SMark Jansen 
607*96c0f7d3SMark Jansen     ULONG refCount = psv->Release();
608*96c0f7d3SMark Jansen     ok(refCount == 0, "refCount = %lu\n", refCount);
609*96c0f7d3SMark Jansen 
610*96c0f7d3SMark Jansen     static message release_list[] =
611*96c0f7d3SMark Jansen     {
612*96c0f7d3SMark Jansen         message(SFVM_VIEWRELEASE, 0, 0),
613*96c0f7d3SMark Jansen 
614*96c0f7d3SMark Jansen         message(0, 0, 0)
615*96c0f7d3SMark Jansen     };
616*96c0f7d3SMark Jansen 
617*96c0f7d3SMark Jansen     /* Investigate why this fails */
618*96c0f7d3SMark Jansen     if (refCount == 0)
619*96c0f7d3SMark Jansen     {
620*96c0f7d3SMark Jansen         compare_list(release_list);
621*96c0f7d3SMark Jansen     }
622*96c0f7d3SMark Jansen }
623