1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: COM interface test
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include "com_apitest.h"
9
10 #include <winreg.h>
11 #include <mshtmhst.h>
12 #include <shlwapi.h>
13 #include <commoncontrols.h>
14 #include <activscp.h>
15 #include <ndk/rtlfuncs.h>
16
17 #define NDEBUG
18 #include <debug.h>
19
20 #define myskip(c, ...) ((c) ? 0 : (skip(__VA_ARGS__), 1))
21 #define mytrace(...) do { \
22 int debug = winetest_debug; \
23 winetest_debug = 1; \
24 trace(__VA_ARGS__); \
25 winetest_debug = debug; \
26 } while (0)
27
28 typedef struct _KNOWN_INTERFACE
29 {
30 const IID *iid;
31 PCSTR name;
32 PCWSTR wname;
33 BOOLEAN noreg;
34 } KNOWN_INTERFACE;
35 typedef const KNOWN_INTERFACE *PCKNOWN_INTERFACE;
36
37 #undef ID_NAME
38 #define ID_NAME(c) &c, #c, L ## #c
39 static KNOWN_INTERFACE KnownInterfaces[] =
40 {
41 { ID_NAME(IID_IACList), TRUE },
42 { ID_NAME(IID_IACList2), TRUE },
43 { ID_NAME(IID_IADesktopP2), TRUE },
44 { ID_NAME(IID_IAccIdentity) },
45 { ID_NAME(IID_IAccPropServer) },
46 { ID_NAME(IID_IAccPropServices) },
47 { ID_NAME(IID_IAccessible) },
48 { ID_NAME(IID_IAccessibleHandler) },
49 { ID_NAME(IID_IAccessControl), TRUE },
50 { ID_NAME(IID_IAccessor) },
51 { ID_NAME(IID_IACLCustomMRU), TRUE },
52 { ID_NAME(IID_IActiveDesktop), TRUE },
53 { ID_NAME(IID_IActiveDesktopP), TRUE },
54 { ID_NAME(IID_IActionProgress) },
55 { ID_NAME(IID_IActionProgressDialog) },
56 { ID_NAME(IID_IAddressBarParser), TRUE },
57 { ID_NAME(IID_IAddressBand), TRUE },
58 { ID_NAME(IID_IAddressEditBox), TRUE },
59 { ID_NAME(IID_IAsyncMoniker), TRUE },
60 { ID_NAME(IID_IAugmentedShellFolder), TRUE },
61 { ID_NAME(IID_IAugmentedShellFolder2), TRUE },
62 { ID_NAME(IID_IAutoComplete), TRUE },
63 { ID_NAME(IID_IAutoComplete2), TRUE },
64 { ID_NAME(IID_IAutoCompleteDropDown) },
65 { ID_NAME(IID_IBandHost) },
66 { ID_NAME(IID_IBandNavigate), },
67 { ID_NAME(IID_IBandProxy), TRUE },
68 { ID_NAME(IID_IBandSite) },
69 { ID_NAME(IID_IBandSiteHelper), TRUE },
70 { ID_NAME(IID_IBanneredBar), TRUE },
71 { ID_NAME(IID_IBindCtx) },
72 { ID_NAME(IID_IBindEventHandler) },
73 { ID_NAME(IID_IBindHost) },
74 { ID_NAME(IID_IBinding) },
75 { ID_NAME(IID_IBindProtocol), TRUE },
76 { ID_NAME(IID_IBindResource) },
77 { ID_NAME(IID_IBindStatusCallback) },
78 { ID_NAME(IID_IBlockingLock) },
79 { ID_NAME(IID_IBrowserFrameOptions), TRUE },
80 { ID_NAME(IID_IBrowserService) },
81 { ID_NAME(IID_IBrowserService2), TRUE },
82 { ID_NAME(IID_IBrowserService3), TRUE },
83 { ID_NAME(IID_IBrowserService4), TRUE },
84 { ID_NAME(IID_ICDBurn) },
85 { ID_NAME(IID_ICDBurnExt) },
86 { ID_NAME(IID_ICDBurnPriv) },
87 { ID_NAME(IID_ICallFactory), TRUE },
88 { ID_NAME(IID_ICancelMethodCalls), TRUE },
89 { ID_NAME(IID_ICatInformation) },
90 { ID_NAME(IID_ICatRegister) },
91 { ID_NAME(IID_IClassActivator), },
92 { ID_NAME(IID_IClassFactory) },
93 { ID_NAME(IID_IClassFactory2) },
94 { ID_NAME(IID_IClassFactory3), TRUE },
95 { ID_NAME(IID_IClientSecurity), TRUE },
96 { ID_NAME(IID_ICommDlgBrowser) },
97 { ID_NAME(IID_ICommDlgBrowser2) },
98 { ID_NAME(IID_ICommDlgBrowser3) },
99 { ID_NAME(IID_ICompositeFolder) },
100 { ID_NAME(IID_IComputerInfoChangeNotify), },
101 { ID_NAME(IID_IComThreadingInfo), TRUE },
102 { ID_NAME(IID_IConnectionPoint) },
103 { ID_NAME(IID_IConnectionPointContainer) },
104 { ID_NAME(IID_IContext), TRUE },
105 { ID_NAME(IID_IContextMenu), TRUE },
106 { ID_NAME(IID_IContextMenu2), TRUE },
107 { ID_NAME(IID_IContextMenu3), TRUE },
108 { ID_NAME(IID_IContextMenuCB), TRUE },
109 { ID_NAME(IID_IContextMenuSite) },
110 { ID_NAME(IID_IContinue) },
111 { ID_NAME(IID_IContinueCallback) },
112 { ID_NAME(IID_ICopyHookA), TRUE },
113 { ID_NAME(IID_ICopyHookW), TRUE },
114 { ID_NAME(IID_ICurrentWorkingDirectory), TRUE },
115 { ID_NAME(IID_ICustomizeInfoTip) },
116 { ID_NAME(IID_IDVGetEnum), TRUE },
117 { ID_NAME(IID_IDataObject) },
118 //{ ID_NAME(IID_IDefViewID) }, == DefViewFrame3
119 { ID_NAME(IID_IDefViewFrame), TRUE },
120 { ID_NAME(IID_IDefViewFrame3) },
121 { ID_NAME(IID_IDefViewFrameGroup) },
122 { ID_NAME(IID_IDefViewSafety), },
123 { ID_NAME(IID_IDefViewScript), TRUE },
124 { ID_NAME(IID_IDelayedRelease), TRUE },
125 { ID_NAME(IID_IDeskBand) },
126 { ID_NAME(IID_IDeskBandEx) },
127 { ID_NAME(IID_IDeskBar), TRUE },
128 { ID_NAME(IID_IDeskBarClient), TRUE },
129 { ID_NAME(IID_IDeskMovr), TRUE },
130 { ID_NAME(IID_IDiscMasterProgressEvents) },
131 { ID_NAME(IID_IDispatch) },
132 { ID_NAME(IID_IDispatchEx) },
133 { ID_NAME(IID_IDockingWindow) },
134 { ID_NAME(IID_IDockingWindowFrame), TRUE },
135 { ID_NAME(IID_IDockingWindowSite), TRUE },
136 { ID_NAME(IID_IDocViewSite), TRUE },
137 { ID_NAME(IID_IDragSourceHelper), TRUE },
138 { ID_NAME(IID_IDriveFolderExt), TRUE },
139 { ID_NAME(IID_IDropSource) },
140 { ID_NAME(IID_IDropTarget) },
141 { ID_NAME(IID_IDropTargetHelper), TRUE },
142 { ID_NAME(IID_IEFrameAuto) },
143 //{ ID_NAME(IID_IEnumCATID) }, == EnumGUID
144 //{ ID_NAME(IID_IEnumCLSID) }, == EnumGUID
145 { ID_NAME(IID_IEnumCATEGORYINFO) },
146 { ID_NAME(IID_IEnumConnectionPoints) },
147 { ID_NAME(IID_IEnumConnections) },
148 { ID_NAME(IID_IEnumExtraSearch) },
149 { ID_NAME(IID_IEnumGUID) },
150 { ID_NAME(IID_IEnumIDList) },
151 { ID_NAME(IID_IEnumMoniker) },
152 //{ ID_NAME(IID_IEnumNetCfgBindingInterface) },
153 //{ ID_NAME(IID_IEnumNetCfgBindingPath) },
154 { ID_NAME(IID_IEnumNetCfgComponent), TRUE },
155 { ID_NAME(IID_IEnumNetConnection) },
156 { ID_NAME(IID_IEnumShellItems) },
157 { ID_NAME(IID_IEnumSTATSTG) },
158 { ID_NAME(IID_IEnumString) },
159 { ID_NAME(IID_IEnumUnknown) },
160 { ID_NAME(IID_IEnumVARIANT) },
161 { ID_NAME(IID_IErrorLog) },
162 { ID_NAME(IID_IExplorerBrowser) },
163 { ID_NAME(IID_IExplorerToolbar), TRUE },
164 { ID_NAME(IID_IExtractIconA), TRUE },
165 { ID_NAME(IID_IExtractIconW), TRUE },
166 { ID_NAME(IID_IExtractImage) },
167 { ID_NAME(IID_IExtractImage2) },
168 { ID_NAME(IID_IFileDialog) },
169 { ID_NAME(IID_IFileDialog2), TRUE },
170 { ID_NAME(IID_IFileOpenDialog) },
171 { ID_NAME(IID_IFileSaveDialog) },
172 { ID_NAME(IID_IFileSearchBand) },
173 { ID_NAME(IID_IFileViewerA), TRUE },
174 { ID_NAME(IID_IFileViewerSite), TRUE },
175 { ID_NAME(IID_IFileViewerW), TRUE },
176 { ID_NAME(IID_IFilter) },
177 { ID_NAME(IID_IFolderBandPriv) },
178 { ID_NAME(IID_IFolderFilter) },
179 { ID_NAME(IID_IFolderFilterSite) },
180 { ID_NAME(IID_IFolderView) },
181 { ID_NAME(IID_IFolderView2) },
182 { ID_NAME(IID_IFolderViewHost), TRUE },
183 { ID_NAME(IID_IFolderViewOC) },
184 { ID_NAME(IID_IFolderViewSettings) },
185 { ID_NAME(IID_IForegroundTransfer), TRUE },
186 { ID_NAME(IID_IGetNameSpaceExtensionPointer),TRUE},
187 { ID_NAME(IID_IGlobalFolderSettings), TRUE },
188 { ID_NAME(IID_IHWEventHandler) },
189 { ID_NAME(IID_IHWEventHandler2) },
190 { ID_NAME(IID_IHlinkFrame) },
191 { ID_NAME(IID_IImageList), TRUE },
192 { ID_NAME(IID_IImageList2), TRUE },
193 { ID_NAME(IID_IInitializeObject), TRUE },
194 { ID_NAME(IID_IInitializeWithBindCtx) },
195 { ID_NAME(IID_IInitializeWithFile) },
196 { ID_NAME(IID_IInputObject) },
197 { ID_NAME(IID_IInputObjectSite) },
198 { ID_NAME(IID_IInternalUnknown), TRUE },
199 { ID_NAME(IID_IInternetSecurityManager) },
200 { ID_NAME(IID_IInternetZoneManager), TRUE },
201 { ID_NAME(IID_IItemNameLimits) },
202 { ID_NAME(IID_IMarshal) },
203 { ID_NAME(IID_IMarshal2), TRUE },
204 { ID_NAME(IID_IMenuBand), TRUE },
205 { ID_NAME(IID_IMenuPopup), TRUE },
206 { ID_NAME(IID_IModalWindow) },
207 { ID_NAME(IID_IMoniker) },
208 { ID_NAME(IID_IMruDataList), TRUE },
209 { ID_NAME(IID_IMruPidlList), TRUE },
210 { ID_NAME(IID_IMultiMonitorDockingSite), TRUE },
211 { ID_NAME(IID_IMultiQI), TRUE },
212 { ID_NAME(IID_INameSpaceTreeControl), TRUE },
213 { ID_NAME(IID_INamespaceProxy), TRUE },
214 { ID_NAME(IID_INamespaceWalk) },
215 { ID_NAME(IID_INamespaceWalkCB) },
216 { ID_NAME(IID_INamespaceWalkCB2) },
217 { ID_NAME(IID_INetCfg), TRUE },
218 //{ ID_NAME(IID_INetCfgBindingInterface) },
219 //{ ID_NAME(IID_INetCfgBindingPath) },
220 { ID_NAME(IID_INetCfgComponent), TRUE },
221 { ID_NAME(IID_INetCfgComponentBindings), TRUE },
222 { ID_NAME(IID_INetCfgComponentControl), TRUE },
223 { ID_NAME(IID_INetCfgComponentPropertyUi), TRUE },
224 { ID_NAME(IID_INetCfgLock), TRUE },
225 { ID_NAME(IID_INetCfgPnpReconfigCallback), TRUE },
226 { ID_NAME(IID_INetConnectionConnectUi), TRUE },
227 { ID_NAME(IID_INetConnectionPropertyUi), TRUE },
228 { ID_NAME(IID_INetConnectionPropertyUi2), TRUE },
229 { ID_NAME(IID_INetConnectionManager) },
230 { ID_NAME(IID_INetLanConnectionUiInfo), TRUE },
231 { ID_NAME(IID_INewMenuClient) },
232 { ID_NAME(IID_INewShortcutHookA), TRUE },
233 { ID_NAME(IID_INewShortcutHookW), TRUE },
234 { ID_NAME(IID_INewWindowManager) },
235 { ID_NAME(IID_INSCTree), TRUE },
236 { ID_NAME(IID_INSCTree2), TRUE },
237 { ID_NAME(IID_IObjMgr), TRUE },
238 { ID_NAME(IID_IObjectSafety) },
239 { ID_NAME(IID_IObjectWithBackReferences) },
240 { ID_NAME(IID_IObjectWithSite) },
241 { ID_NAME(IID_IOleClientSite) },
242 { ID_NAME(IID_IOleCommandTarget) },
243 { ID_NAME(IID_IOleContainer) },
244 { ID_NAME(IID_IOleControl) },
245 { ID_NAME(IID_IOleControlSite) },
246 { ID_NAME(IID_IOleInPlaceActiveObject) },
247 { ID_NAME(IID_IOleInPlaceFrame) },
248 { ID_NAME(IID_IOleInPlaceObject) },
249 { ID_NAME(IID_IOleInPlaceObjectWindowless), TRUE },
250 { ID_NAME(IID_IOleInPlaceSite) },
251 { ID_NAME(IID_IOleInPlaceSiteEx) },
252 { ID_NAME(IID_IOleInPlaceSiteWindowless), TRUE },
253 { ID_NAME(IID_IOleInPlaceUIWindow) },
254 { ID_NAME(IID_IOleItemContainer), },
255 { ID_NAME(IID_IOleLink), },
256 { ID_NAME(IID_IOleObject) },
257 { ID_NAME(IID_IOleWindow) },
258 { ID_NAME(IID_IParentAndItem) },
259 { ID_NAME(IID_IParseDisplayName), },
260 { ID_NAME(IID_IPersist) },
261 { ID_NAME(IID_IPersistFile) },
262 { ID_NAME(IID_IPersistFolder) },
263 { ID_NAME(IID_IPersistFolder2) },
264 { ID_NAME(IID_IPersistFolder3) },
265 { ID_NAME(IID_IPersistFreeThreadedObject), TRUE },
266 { ID_NAME(IID_IPersistHistory) },
267 { ID_NAME(IID_IPersistIDList) },
268 { ID_NAME(IID_IPersistMemory) },
269 { ID_NAME(IID_IPersistPropertyBag) },
270 { ID_NAME(IID_IPersistPropertyBag2) },
271 { ID_NAME(IID_IPersistStorage) },
272 { ID_NAME(IID_IPersistStream) },
273 { ID_NAME(IID_IPersistStreamInit) },
274 { ID_NAME(IID_IPreviewHandler) },
275 { ID_NAME(IID_IPreviewHandlerFrame) },
276 { ID_NAME(IID_IPreviewHandlerVisuals) },
277 { ID_NAME(IID_IProgressDialog), TRUE },
278 { ID_NAME(IID_IPropertyBag) },
279 { ID_NAME(IID_IPropertyBag2) },
280 { ID_NAME(IID_IPropertySetStorage) },
281 { ID_NAME(IID_IPropertyStore) },
282 { ID_NAME(IID_IPropSheetPage), TRUE },
283 { ID_NAME(IID_IProvideClassInfo) },
284 { ID_NAME(IID_IProvideClassInfo2) },
285 { ID_NAME(IID_IQueryAssociations), TRUE },
286 { ID_NAME(IID_IQueryCancelAutoPlay) },
287 { ID_NAME(IID_IQueryInfo), TRUE },
288 { ID_NAME(IID_IQuickActivate) },
289 { ID_NAME(IID_IRegTreeOptions), TRUE },
290 { ID_NAME(IID_IRemoteComputer) },
291 { ID_NAME(IID_IResolveShellLink) },
292 { ID_NAME(IID_IROTData), },
293 { ID_NAME(IID_IRpcOptions), TRUE },
294 { ID_NAME(IID_IRunnableObject) },
295 { ID_NAME(IID_IRunningObjectTable), },
296 { ID_NAME(IID_ISLTracker), TRUE },
297 { ID_NAME(IID_IScriptErrorList) },
298 { ID_NAME(IID_ISearch) },
299 { ID_NAME(IID_ISearchAssistantOC) },
300 { ID_NAME(IID_ISearchAssistantOC2) },
301 { ID_NAME(IID_ISearchAssistantOC3) },
302 { ID_NAME(IID_ISearchBar) },
303 { ID_NAME(IID_ISearches) },
304 { ID_NAME(IID_ISecMgrCacheSeedTarget) },
305 { ID_NAME(IID_IServerSecurity), TRUE },
306 { ID_NAME(IID_IServiceProvider) },
307 { ID_NAME(IID_IShellApp), TRUE },
308 { ID_NAME(IID_IShellBrowser) },
309 { ID_NAME(IID_IShellBrowserService), TRUE },
310 { ID_NAME(IID_IShellChangeNotify), TRUE },
311 { ID_NAME(IID_IShellCopyHookA), TRUE },
312 { ID_NAME(IID_IShellCopyHookW), TRUE },
313 { ID_NAME(IID_IShellDesktopTray), TRUE },
314 { ID_NAME(IID_IShellDetails), TRUE },
315 { ID_NAME(IID_IShellDispatch) },
316 { ID_NAME(IID_IShellDispatch2) },
317 { ID_NAME(IID_IShellDispatch3) },
318 { ID_NAME(IID_IShellDispatch4) },
319 { ID_NAME(IID_IShellDispatch5), TRUE },
320 { ID_NAME(IID_IShellDispatch6), TRUE },
321 { ID_NAME(IID_IShellExecuteHookA), TRUE },
322 { ID_NAME(IID_IShellExecuteHookW), TRUE },
323 { ID_NAME(IID_IShellExtInit), TRUE },
324 { ID_NAME(IID_IShellFavoritesNameSpace) },
325 { ID_NAME(IID_IShellFolder) },
326 { ID_NAME(IID_IShellFolder2) },
327 { ID_NAME(IID_IShellFolderBand), TRUE },
328 { ID_NAME(IID_IShellFolderSearchable), TRUE },
329 { ID_NAME(IID_IShellFolderSearchableCallback), TRUE },
330 { ID_NAME(IID_IShellFolderView), TRUE },
331 { ID_NAME(IID_IShellFolderViewCB), TRUE },
332 { ID_NAME(IID_IShellFolderViewDual) },
333 { ID_NAME(IID_IShellFolderViewDual2) },
334 { ID_NAME(IID_IShellFolderViewDual3), TRUE },
335 { ID_NAME(IID_IShellFolderViewType), TRUE },
336 { ID_NAME(IID_IShellIcon) },
337 { ID_NAME(IID_IShellIconOverlay), TRUE },
338 { ID_NAME(IID_IShellIconOverlayIdentifier), TRUE },
339 { ID_NAME(IID_IShellImageData), TRUE },
340 { ID_NAME(IID_IShellImageDataAbort), TRUE },
341 { ID_NAME(IID_IShellImageDataFactory), TRUE },
342 { ID_NAME(IID_IShellItem) },
343 { ID_NAME(IID_IShellItem2) },
344 { ID_NAME(IID_IShellItemArray) },
345 { ID_NAME(IID_IShellItemFilter) },
346 { ID_NAME(IID_IShellLinkA) },
347 { ID_NAME(IID_IShellLinkDataList), TRUE },
348 { ID_NAME(IID_IShellLinkDual) },
349 { ID_NAME(IID_IShellLinkDual2) },
350 { ID_NAME(IID_IShellLinkW) },
351 { ID_NAME(IID_IShellMenu), TRUE },
352 { ID_NAME(IID_IShellMenu2), TRUE },
353 { ID_NAME(IID_IShellMenuAcc), TRUE },
354 { ID_NAME(IID_IShellMenuCallback), TRUE },
355 { ID_NAME(IID_IShellNameSpace) },
356 { ID_NAME(IID_IShellPropSheetExt), TRUE },
357 { ID_NAME(IID_IShellService), TRUE },
358 { ID_NAME(IID_IShellTaskScheduler), TRUE },
359 { ID_NAME(IID_IShellUIHelper) },
360 { ID_NAME(IID_IShellUIHelper2), TRUE },
361 { ID_NAME(IID_IShellView) },
362 { ID_NAME(IID_IShellView2) },
363 { ID_NAME(IID_IShellView3) },
364 { ID_NAME(IID_IShellWindows) },
365 { ID_NAME(IID_ISpecifyPropertyPages) },
366 { ID_NAME(IID_IStorage) },
367 { ID_NAME(IID_IStream) },
368 { ID_NAME(IID_ISurrogate) },
369 { ID_NAME(IID_ISynchronize) },
370 { ID_NAME(IID_ISynchronizeContainer), TRUE },
371 { ID_NAME(IID_ISynchronizeEvent), TRUE },
372 { ID_NAME(IID_ISynchronizeHandle), TRUE },
373 { ID_NAME(IID_ITargetEmbedding) },
374 { ID_NAME(IID_ITargetFrame) },
375 { ID_NAME(IID_ITargetFrame2) },
376 { ID_NAME(IID_ITargetFramePriv) },
377 { ID_NAME(IID_ITargetFramePriv2) },
378 { ID_NAME(IID_ITargetNotify) },
379 { ID_NAME(IID_ITaskbarList) },
380 { ID_NAME(IID_ITaskbarList2) },
381 { ID_NAME(IID_ITaskbarList3), TRUE },
382 { ID_NAME(IID_ITaskbarList4), TRUE },
383 { ID_NAME(IID_ITrackShellMenu), TRUE },
384 /* This interface is completely different between PSDK and registry/shell32 */
385 { ID_NAME(IID_ITransferAdviseSink), TRUE },
386 #define IID_ITransferAdviseSink IID_ITransferAdviseSinkPriv
387 { ID_NAME(IID_ITransferAdviseSink) },
388 #undef IID_ITransferAdviseSink
389 { ID_NAME(IID_ITransferDestination), TRUE },
390 { ID_NAME(IID_ITransferSource), TRUE },
391 { ID_NAME(IID_ITranslateShellChangeNotify), TRUE },
392 { ID_NAME(IID_ITrayPriv), TRUE },
393 { ID_NAME(IID_ITrayPriv2), TRUE },
394 { ID_NAME(IID_IUnknown) },
395 { ID_NAME(IID_IURLSearchHook), TRUE },
396 { ID_NAME(IID_IURLSearchHook2), TRUE },
397 { ID_NAME(IID_IUrlHistoryNotify) },
398 { ID_NAME(IID_IUrlHistoryStg) },
399 { ID_NAME(IID_IUrlHistoryStg2) },
400 { ID_NAME(IID_IViewObject) },
401 { ID_NAME(IID_IViewObject2) },
402 { ID_NAME(IID_IViewObjectEx), TRUE },
403 { ID_NAME(IID_IVisualProperties) },
404 { ID_NAME(IID_IWebBrowser) },
405 { ID_NAME(IID_IWebBrowser2) },
406 { ID_NAME(IID_IWebBrowserApp) },
407 { ID_NAME(IID_IWebBrowserPriv) },
408 { ID_NAME(IID_IWebBrowserPriv2) },
409 { ID_NAME(IID_IWinEventHandler), TRUE },
410
411 { ID_NAME(IID_DFConstraint), TRUE },
412 { ID_NAME(DIID__SearchAssistantEvents) },
413 { ID_NAME(DIID_DShellFolderViewEvents) },
414 { ID_NAME(DIID_DShellNameSpaceEvents) },
415 { ID_NAME(DIID_DShellWindowsEvents) },
416 { ID_NAME(DIID_DWebBrowserEvents) },
417 { ID_NAME(DIID_DWebBrowserEvents2) },
418 { ID_NAME(DIID_XMLDOMDocumentEvents ) },
419
420 { ID_NAME(IID_CDefView), TRUE },
421 { ID_NAME(IID_Folder) },
422 { ID_NAME(IID_Folder2) },
423 { ID_NAME(IID_Folder3) },
424 { ID_NAME(IID_FolderItem) },
425 { ID_NAME(IID_FolderItem2) },
426 { ID_NAME(IID_FolderItems) },
427 { ID_NAME(IID_FolderItems2) },
428 { ID_NAME(IID_FolderItems3) },
429 { ID_NAME(IID_FolderItemVerb) },
430 { ID_NAME(IID_FolderItemVerbs) },
431
432 { ID_NAME(CLSID_ShellDesktop), TRUE },
433
434 { ID_NAME(IID_IQueryContinue) },
435 { ID_NAME(IID_IUserNotification) },
436 { ID_NAME(IID_IUserNotificationCallback) }, // On Vista+
437 { ID_NAME(IID_IUserNotification2) }, // On Vista+
438
439 { ID_NAME(IID_IAggregateFilterCondition) },
440 { ID_NAME(IID_IAliasRegistrationCallback), TRUE },
441 { ID_NAME(IID_IAssociationArrayInitialize), TRUE },
442 { ID_NAME(IID_IAssociationList), TRUE },
443 { ID_NAME(IID_IBackReferencedObject), TRUE },
444 { ID_NAME(IID_IBasePropPage), TRUE },
445 { ID_NAME(IID_ICommonLayoutDefinition), TRUE },
446 { ID_NAME(IID_IControlPanelEnumerator), TRUE },
447 { ID_NAME(IID_IDelegateHostItemContainer), TRUE },
448 { ID_NAME(IID_IDrawPropertyControl), TRUE },
449 { ID_NAME(IID_IEnumAssociationElements), TRUE },
450 { ID_NAME(IID_IEnumerateAssociationElements),TRUE },
451 { ID_NAME(IID_IExecuteCommand), TRUE },
452 { ID_NAME(IID_IFilterCondition) },
453 { ID_NAME(IID_IFolderNotify), TRUE },
454 { ID_NAME(IID_IFolderProperties), TRUE },
455 { ID_NAME(IID_IFolderType), TRUE },
456 { ID_NAME(IID_IFolderWithSearchRoot), TRUE },
457 { ID_NAME(IID_IFrameLayoutDefinition), TRUE },
458 { ID_NAME(IID_IItemFilter), TRUE },
459 { ID_NAME(IID_IItemFilterOwner), TRUE },
460 { ID_NAME(IID_ILocalizableItemParent), TRUE },
461 { ID_NAME(IID_INewItemAdvisor), TRUE },
462 { ID_NAME(IID_IObjectWithAssociationElement),TRUE },
463 { ID_NAME(IID_IObjectWithAssociationList), TRUE },
464 { ID_NAME(IID_IObjectWithQuerySource), TRUE },
465 { ID_NAME(IID_IObjectWithSelection), TRUE },
466 { ID_NAME(IID_IPersistString2), TRUE },
467 { ID_NAME(IID_IPrinterFolder), TRUE },
468 { ID_NAME(IID_IPropertyControl), TRUE },
469 { ID_NAME(IID_IPropertyControlBase), TRUE },
470 { ID_NAME(IID_IPropertyControlSite), TRUE },
471 { ID_NAME(IID_IRegItemCustomAttributes), TRUE },
472 { ID_NAME(IID_IRegItemCustomEnumerator), TRUE },
473 { ID_NAME(IID_IRegItemFolder), TRUE },
474 { ID_NAME(IID_IRootAndRelativeParsingFolder),TRUE },
475 { ID_NAME(IID_IScope), TRUE },
476 { ID_NAME(IID_IScopeItem), TRUE },
477 { ID_NAME(IID_IShellBrowserServce), TRUE },
478 { ID_NAME(IID_IShellFolder3), TRUE },
479 { ID_NAME(IID_ITaskCondition), TRUE },
480 { ID_NAME(IID_ITaskConditionCombiner), TRUE },
481 { ID_NAME(IID_ITaskConditionInit), TRUE },
482 { ID_NAME(IID_ITransferProvider), TRUE },
483 { ID_NAME(IID_IUserEventTimer) },
484 { ID_NAME(IID_IUserEventTimerCallback) },
485 { ID_NAME(IID_IAssociationArrayOld), TRUE },
486 { ID_NAME(IID_IAssociationArray), TRUE },
487 #define IID_IDriveFolderExt IID_IDriveFolderExtOld
488 { ID_NAME(IID_IDriveFolderExt) },
489 #undef IID_IDriveFolderExt
490 { ID_NAME(IID_IPinnedListOld), TRUE },
491 { ID_NAME(IID_IPinnedList), TRUE },
492 { ID_NAME(IID_IAttachmentExecute), TRUE },
493
494 // + MMC stuff
495 { ID_NAME(IID_IComponentData), TRUE },
496 { ID_NAME(IID_IConsole), TRUE },
497 { ID_NAME(IID_IConsole2), TRUE },
498 { ID_NAME(IID_IConsoleNameSpace), TRUE },
499 { ID_NAME(IID_IConsoleNameSpace2), TRUE },
500 { ID_NAME(IID_IPropertySheetCallback), TRUE },
501 { ID_NAME(IID_IPropertySheetProvider), TRUE },
502 { ID_NAME(IID_IExtendPropertySheet), TRUE },
503 { ID_NAME(IID_IExtendPropertySheet2), TRUE },
504 { ID_NAME(IID_IHeaderCtrl), TRUE },
505 { ID_NAME(IID_IToolbar), TRUE },
506 { ID_NAME(IID_IImageList_mmc), TRUE },
507 { ID_NAME(IID_IConsoleVerb), TRUE },
508 { ID_NAME(IID_ISnapInAbout), TRUE },
509 // - MMC stuff
510
511 { ID_NAME(IID_ICertificateManager), TRUE },
512 };
513 static const INT KnownInterfaceCount = RTL_NUMBER_OF(KnownInterfaces);
514
515 static
516 PCKNOWN_INTERFACE
FindInterface(_In_ const IID * iid)517 FindInterface(
518 _In_ const IID *iid)
519 {
520 INT i;
521
522 for (i = 0; i < KnownInterfaceCount; i++)
523 if (IsEqualIID(KnownInterfaces[i].iid, iid))
524 return &KnownInterfaces[i];
525 ASSERT(i != KnownInterfaceCount);
526 return NULL;
527 }
528
529 static
530 BOOLEAN
IsInterfaceExpected(_In_ PCCLASS_AND_INTERFACES class,_In_ const IID * iid)531 IsInterfaceExpected(
532 _In_ PCCLASS_AND_INTERFACES class,
533 _In_ const IID *iid)
534 {
535 INT i;
536
537 for (i = 0; class->ifaces[i].iid; i++)
538 if (IsEqualIID(class->ifaces[i].iid, iid))
539 return TRUE;
540 return FALSE;
541 }
542
543 #define INTF_NOT_EXPOSED LONG_MAX
544 static
545 LONG
GetInterfaceOffset(_In_ PUNKNOWN pUnk,_In_ const IID * iid)546 GetInterfaceOffset(
547 _In_ PUNKNOWN pUnk,
548 _In_ const IID *iid)
549 {
550 HRESULT hr;
551 PVOID pObj;
552 PUNKNOWN pUnk2;
553 LONG offset;
554
555 hr = IUnknown_QueryInterface(pUnk, iid, &pObj);
556 ok(hr == S_OK || hr == E_NOINTERFACE, "IUnknown::QueryInterface returned 0x%lx\n", hr);
557 if (FAILED(hr))
558 return INTF_NOT_EXPOSED;
559
560 pUnk2 = pObj;
561 offset = (LONG_PTR)pObj - (LONG_PTR)pUnk;
562 IUnknown_Release(pUnk2);
563 return offset;
564 }
565
566 static
567 VOID
TestModuleInterfaces(_In_ PCCLASS_AND_INTERFACES ExpectedInterfaces,_In_ INT ExpectedInterfaceCount)568 TestModuleInterfaces(
569 _In_ PCCLASS_AND_INTERFACES ExpectedInterfaces,
570 _In_ INT ExpectedInterfaceCount)
571 {
572 HRESULT hr;
573 PVOID pObj;
574 PUNKNOWN pUnk;
575 INT iClass, iIntf;
576 PCCLASS_AND_INTERFACES class;
577
578 for (iClass = 0; iClass < ExpectedInterfaceCount; iClass++)
579 {
580 class = &ExpectedInterfaces[iClass];
581 hr = CoCreateInstance(class->clsid,
582 NULL,
583 CLSCTX_INPROC_SERVER,
584 &IID_IUnknown,
585 &pObj);
586 ok(hr == S_OK, "CoCreateInstance failed. hr=0x%lx\n", hr);
587 if (FAILED(hr))
588 {
589 skip("Failed to instantiate %s.\n", class->name);
590 continue;
591 }
592
593 pUnk = pObj;
594
595 /* Check that all expected interfaces are present and have the right offset */
596 for (iIntf = 0; class->ifaces[iIntf].iid; iIntf++)
597 {
598 PCKNOWN_INTERFACE iface = FindInterface(class->ifaces[iIntf].iid);
599 LONG offset = GetInterfaceOffset(pUnk, iface->iid);
600 if (offset == INTF_NOT_EXPOSED)
601 ok(0, "%s is missing %s (offset %ld)\n", class->name, iface->name, class->ifaces[iIntf].offset);
602 else if (class->ifaces[iIntf].offset != FARAWY)
603 {
604 #ifdef FAIL_WRONG_OFFSET
605 ok(offset == class->ifaces[iIntf].offset, "%s, %s offset is %ld, expected %ld\n", class->name, iface->name, offset, class->ifaces[iIntf].offset);
606 #else
607 if (offset != class->ifaces[iIntf].offset)
608 mytrace("%s, %s offset is %ld, expected %ld\n", class->name, iface->name, offset, class->ifaces[iIntf].offset);
609 #endif
610 }
611 }
612
613 /* Check that none other than the expected interfaces are present */
614 for (iIntf = 0; iIntf < KnownInterfaceCount; iIntf++)
615 {
616 PCKNOWN_INTERFACE iface = &KnownInterfaces[iIntf];
617 LONG offset;
618 if (IsInterfaceExpected(class, iface->iid))
619 continue;
620 offset = GetInterfaceOffset(pUnk, iface->iid);
621 #ifdef GENERATE_TABLE_ENTRIES
622 ok(offset == INTF_NOT_EXPOSED, "%s: { %s0x%lx, &%s },\n", class->name, offset < 0 ? "-" : "", offset < 0 ? -offset : offset, iface->name);
623 #else
624 ok(offset == INTF_NOT_EXPOSED, "%s exposes %s (offset %ld), but shouldn't\n", class->name, iface->name, offset);
625 #endif
626 }
627
628 // TODO: do some aggregation
629
630 IUnknown_Release(pUnk);
631 }
632 }
633
634 static
635 VOID
TestModuleRegistry(_In_ PCWSTR ModuleName,_In_ PCCLASS_AND_INTERFACES ExpectedInterfaces,_In_ INT ExpectedInterfaceCount)636 TestModuleRegistry(
637 _In_ PCWSTR ModuleName,
638 _In_ PCCLASS_AND_INTERFACES ExpectedInterfaces,
639 _In_ INT ExpectedInterfaceCount)
640 {
641 INT iClass;
642 PCCLASS_AND_INTERFACES class;
643 HKEY hKeyClasses;
644 LONG result;
645
646 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID", 0, KEY_ENUMERATE_SUB_KEYS, &hKeyClasses);
647 ok(result == NO_ERROR, "Failed to open classes key, error %lu\n", result);
648 if (!myskip(result == NO_ERROR, "No classes key\n"))
649 {
650 for (iClass = 0; iClass < ExpectedInterfaceCount; iClass++)
651 {
652 HKEY hKey;
653 HKEY hKeyServer;
654 NTSTATUS status;
655 UNICODE_STRING clsid;
656 DWORD type;
657 WCHAR data[100];
658 DWORD dataSize;
659 PCWSTR expectedThreadingModel;
660
661 class = &ExpectedInterfaces[iClass];
662 status = RtlStringFromGUID(class->clsid, &clsid);
663 ok(status == STATUS_SUCCESS, "Failed to convert guid to string for %s, status %lx\n", class->name, status);
664 if (myskip(NT_SUCCESS(status), "No guid string\n"))
665 continue;
666
667 result = RegOpenKeyExW(hKeyClasses, clsid.Buffer, 0, KEY_ENUMERATE_SUB_KEYS, &hKey);
668 ok(result == NO_ERROR, "Failed to open key for %s, error %lu\n", class->name, result);
669 RtlFreeUnicodeString(&clsid);
670 if (myskip(result == NO_ERROR, "No key\n"))
671 continue;
672
673 result = RegOpenKeyExW(hKey, L"InProcServer32", 0, KEY_QUERY_VALUE, &hKeyServer);
674 ok(result == NO_ERROR, "Failed to open key for %s, error %lu\n", class->name, result);
675 RegCloseKey(hKey);
676 if (myskip(result == NO_ERROR, "No key\n"))
677 continue;
678
679 dataSize = sizeof(data);
680 result = RegQueryValueExW(hKeyServer, NULL, NULL, &type, (PBYTE)data, &dataSize);
681 ok(result == NO_ERROR, "Failed to query value for %s, error %lu\n", class->name, result);
682 if (!myskip(result == NO_ERROR, "No module name\n"))
683 {
684 ok(type == REG_SZ || type == REG_EXPAND_SZ, "type %lu for %s\n", type, class->name);
685 ok(dataSize % sizeof(WCHAR) == 0, "size %lu for %s\n", dataSize, class->name);
686 ok(dataSize <= sizeof(data), "size %lu for %s\n", dataSize, class->name);
687 ok(data[dataSize / sizeof(WCHAR) - 1] == UNICODE_NULL, "Not null terminated for %s\n", class->name);
688 // TODO: Use SearchPath (or assume everything's in system32) and do a proper full path compare
689 PathStripPathW(data);
690 PathRemoveExtensionW(data);
691 ok(!_wcsicmp(data, ModuleName), "Server is %ls, expected %ls for %s\n", data, ModuleName, class->name);
692 }
693
694 dataSize = sizeof(data);
695 result = RegQueryValueExW(hKeyServer, L"ThreadingModel", NULL, &type, (PBYTE)data, &dataSize);
696 ok(result == NO_ERROR, "Failed to query value for %s, error %lu\n", class->name, result);
697 if (!myskip(result == NO_ERROR, "No ThreadingModel\n"))
698 {
699 ok(type == REG_SZ || type == REG_EXPAND_SZ, "type %lu for %s\n", type, class->name);
700 ok(dataSize % sizeof(WCHAR) == 0, "size %lu for %s\n", dataSize, class->name);
701 ok(dataSize <= sizeof(data), "size %lu for %s\n", dataSize, class->name);
702 ok(data[dataSize / sizeof(WCHAR) - 1] == UNICODE_NULL, "Not null terminated for %s\n", class->name);
703 expectedThreadingModel = class->ThreadingModel;
704 if (!expectedThreadingModel)
705 expectedThreadingModel = L"Apartment";
706 ok(!_wcsicmp(data, expectedThreadingModel), "Server is %ls, expected %ls for %s\n", data, expectedThreadingModel, class->name);
707 }
708
709 RegCloseKey(hKeyServer);
710 }
711 RegCloseKey(hKeyClasses);
712 }
713 }
714
715 static
716 VOID
TestManualInstantiation(_In_ PCWSTR ModuleName,_In_ PCCLASS_AND_INTERFACES ExpectedInterfaces,_In_ INT ExpectedInterfaceCount)717 TestManualInstantiation(
718 _In_ PCWSTR ModuleName,
719 _In_ PCCLASS_AND_INTERFACES ExpectedInterfaces,
720 _In_ INT ExpectedInterfaceCount)
721 {
722 INT iClass;
723 PCCLASS_AND_INTERFACES class;
724 HRESULT (__stdcall *DllGetClassObject)(REFCLSID, REFIID, PVOID *);
725
726 DllGetClassObject = (PVOID)GetProcAddress(GetModuleHandleW(ModuleName), "DllGetClassObject");
727 ok(DllGetClassObject != NULL, "DllGetClassObject not found in %ls, error %lu\n", ModuleName, GetLastError());
728 if (myskip(DllGetClassObject != NULL, "No DllGetClassObject\n"))
729 return;
730
731 for (iClass = 0; iClass < ExpectedInterfaceCount; iClass++)
732 {
733 PVOID pv;
734 HRESULT hr;
735 class = &ExpectedInterfaces[iClass];
736 hr = DllGetClassObject(class->clsid, &IID_IClassFactory, &pv);
737 ok(hr == S_OK, "DllGetClassObject failed for %s, hr = 0x%lx\n", class->name, hr);
738 if (!myskip(SUCCEEDED(hr), "No class factory\n"))
739 {
740 IClassFactory *pCF = pv;
741 hr = IClassFactory_CreateInstance(pCF, NULL, &IID_IUnknown, &pv);
742 ok(hr == S_OK, "IClassFactory::CreateInstance failed for %s, hr = 0x%lx\n", class->name, hr);
743 if (!myskip(SUCCEEDED(hr), "No instance\n"))
744 {
745 IUnknown *pUnk = pv;
746 IUnknown_Release(pUnk);
747 }
748 IClassFactory_Release(pCF);
749 }
750 }
751 }
752
753 VOID
TestClasses(_In_ PCWSTR ModuleName,_In_ PCCLASS_AND_INTERFACES ExpectedInterfaces,_In_ INT ExpectedInterfaceCount)754 TestClasses(
755 _In_ PCWSTR ModuleName,
756 _In_ PCCLASS_AND_INTERFACES ExpectedInterfaces,
757 _In_ INT ExpectedInterfaceCount)
758 {
759 HRESULT hr;
760
761 hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
762 ok(hr == S_OK, "CoInitializeEx failed. hr=0x%lx\n", hr);
763 if (myskip(SUCCEEDED(hr), "Failed to initialize COM. Cannot perform tests\n"))
764 return;
765
766 TestModuleInterfaces(ExpectedInterfaces, ExpectedInterfaceCount);
767 TestModuleRegistry(ModuleName, ExpectedInterfaces, ExpectedInterfaceCount);
768 TestManualInstantiation(ModuleName, ExpectedInterfaces, ExpectedInterfaceCount);
769
770 CoUninitialize();
771 }
772
773 static
774 VOID
TestInterfaceRegistry(_In_ PCKNOWN_INTERFACE Interfaces,_In_ INT InterfaceCount)775 TestInterfaceRegistry(
776 _In_ PCKNOWN_INTERFACE Interfaces,
777 _In_ INT InterfaceCount)
778 {
779 INT i;
780 HKEY hKeyInterface;
781 LONG result;
782
783 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Classes\\Interface", 0, KEY_ENUMERATE_SUB_KEYS, &hKeyInterface);
784 ok(result == NO_ERROR, "Failed to open interface key, error %lu\n", result);
785 if (!myskip(result == NO_ERROR, "No interface key\n"))
786 {
787 for (i = 0; i < InterfaceCount; i++)
788 {
789 HKEY hKey;
790 NTSTATUS status;
791 UNICODE_STRING iid;
792 DWORD type;
793 WCHAR data[100];
794 DWORD dataSize;
795 PCKNOWN_INTERFACE iface;
796 PCWSTR expectedName;
797
798 iface = &Interfaces[i];
799 status = RtlStringFromGUID(iface->iid, &iid);
800 ok(status == STATUS_SUCCESS, "Failed to convert guid to string for %s, status %lx\n", iface->name, status);
801 if (myskip(NT_SUCCESS(status), "No guid string\n"))
802 continue;
803
804 result = RegOpenKeyExW(hKeyInterface, iid.Buffer, 0, KEY_QUERY_VALUE, &hKey);
805 if (iface->noreg)
806 {
807 ok(result == ERROR_FILE_NOT_FOUND, "RegOpenKeyEx returned %lu for %s\n", result, iface->name);
808 }
809 else
810 {
811 ok(result == NO_ERROR, "Failed to open key for %s, error %lu\n", iface->name, result);
812 (void)myskip(result == NO_ERROR, "No key\n");
813 }
814 RtlFreeUnicodeString(&iid);
815 if (result != NO_ERROR)
816 continue;
817
818 dataSize = sizeof(data);
819 result = RegQueryValueExW(hKey, NULL, NULL, &type, (PBYTE)data, &dataSize);
820 ok(result == NO_ERROR, "Failed to query value for %s, error %lu\n", iface->name, result);
821 if (!myskip(result == NO_ERROR, "No module name\n"))
822 {
823 ok(type == REG_SZ, "type %lu for %s\n", type, iface->name);
824 ok(dataSize % sizeof(WCHAR) == 0, "size %lu for %s\n", dataSize, iface->name);
825 ok(dataSize <= sizeof(data), "size %lu for %s\n", dataSize, iface->name);
826 ok(data[dataSize / sizeof(WCHAR) - 1] == UNICODE_NULL, "Not null terminated for %s\n", iface->name);
827 expectedName = wcschr(iface->wname, L'_');
828 if (expectedName)
829 expectedName++;
830 else
831 expectedName = iface->wname;
832 ok(!_wcsicmp(data, expectedName), "Name is %ls, expected %ls\n", data, expectedName);
833 }
834
835 RegCloseKey(hKey);
836 }
837 RegCloseKey(hKeyInterface);
838 }
839 }
840
START_TEST(interfaces)841 START_TEST(interfaces)
842 {
843 TestInterfaceRegistry(KnownInterfaces, KnownInterfaceCount);
844 }
845