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_IMultiMonitorDockingSite), TRUE }, 209 { ID_NAME(IID_IMultiQI), TRUE }, 210 { ID_NAME(IID_INameSpaceTreeControl), TRUE }, 211 { ID_NAME(IID_INamespaceProxy), TRUE }, 212 { ID_NAME(IID_INamespaceWalk) }, 213 { ID_NAME(IID_INamespaceWalkCB) }, 214 { ID_NAME(IID_INamespaceWalkCB2) }, 215 { ID_NAME(IID_INetCfg), TRUE }, 216 //{ ID_NAME(IID_INetCfgBindingInterface) }, 217 //{ ID_NAME(IID_INetCfgBindingPath) }, 218 { ID_NAME(IID_INetCfgComponent), TRUE }, 219 { ID_NAME(IID_INetCfgComponentBindings), TRUE }, 220 { ID_NAME(IID_INetCfgComponentControl), TRUE }, 221 { ID_NAME(IID_INetCfgComponentPropertyUi), TRUE }, 222 { ID_NAME(IID_INetCfgLock), TRUE }, 223 { ID_NAME(IID_INetCfgPnpReconfigCallback), TRUE }, 224 { ID_NAME(IID_INetConnectionConnectUi), TRUE }, 225 { ID_NAME(IID_INetConnectionPropertyUi), TRUE }, 226 { ID_NAME(IID_INetConnectionPropertyUi2), TRUE }, 227 { ID_NAME(IID_INetConnectionManager) }, 228 { ID_NAME(IID_INetLanConnectionUiInfo), TRUE }, 229 { ID_NAME(IID_INewMenuClient) }, 230 { ID_NAME(IID_INewShortcutHookA), TRUE }, 231 { ID_NAME(IID_INewShortcutHookW), TRUE }, 232 { ID_NAME(IID_INewWindowManager) }, 233 { ID_NAME(IID_INSCTree), TRUE }, 234 { ID_NAME(IID_INSCTree2), TRUE }, 235 { ID_NAME(IID_IObjMgr), TRUE }, 236 { ID_NAME(IID_IObjectSafety) }, 237 { ID_NAME(IID_IObjectWithBackReferences) }, 238 { ID_NAME(IID_IObjectWithSite) }, 239 { ID_NAME(IID_IOleClientSite) }, 240 { ID_NAME(IID_IOleCommandTarget) }, 241 { ID_NAME(IID_IOleContainer) }, 242 { ID_NAME(IID_IOleControl) }, 243 { ID_NAME(IID_IOleControlSite) }, 244 { ID_NAME(IID_IOleInPlaceActiveObject) }, 245 { ID_NAME(IID_IOleInPlaceFrame) }, 246 { ID_NAME(IID_IOleInPlaceObject) }, 247 { ID_NAME(IID_IOleInPlaceObjectWindowless), TRUE }, 248 { ID_NAME(IID_IOleInPlaceSite) }, 249 { ID_NAME(IID_IOleInPlaceSiteEx) }, 250 { ID_NAME(IID_IOleInPlaceSiteWindowless), TRUE }, 251 { ID_NAME(IID_IOleInPlaceUIWindow) }, 252 { ID_NAME(IID_IOleItemContainer), }, 253 { ID_NAME(IID_IOleLink), }, 254 { ID_NAME(IID_IOleObject) }, 255 { ID_NAME(IID_IOleWindow) }, 256 { ID_NAME(IID_IParentAndItem) }, 257 { ID_NAME(IID_IParseDisplayName), }, 258 { ID_NAME(IID_IPersist) }, 259 { ID_NAME(IID_IPersistFile) }, 260 { ID_NAME(IID_IPersistFolder) }, 261 { ID_NAME(IID_IPersistFolder2) }, 262 { ID_NAME(IID_IPersistFolder3) }, 263 { ID_NAME(IID_IPersistFreeThreadedObject), TRUE }, 264 { ID_NAME(IID_IPersistHistory) }, 265 { ID_NAME(IID_IPersistIDList) }, 266 { ID_NAME(IID_IPersistMemory) }, 267 { ID_NAME(IID_IPersistPropertyBag) }, 268 { ID_NAME(IID_IPersistPropertyBag2) }, 269 { ID_NAME(IID_IPersistStorage) }, 270 { ID_NAME(IID_IPersistStream) }, 271 { ID_NAME(IID_IPersistStreamInit) }, 272 { ID_NAME(IID_IPreviewHandler) }, 273 { ID_NAME(IID_IPreviewHandlerFrame) }, 274 { ID_NAME(IID_IPreviewHandlerVisuals) }, 275 { ID_NAME(IID_IProgressDialog), TRUE }, 276 { ID_NAME(IID_IPropertyBag) }, 277 { ID_NAME(IID_IPropertyBag2) }, 278 { ID_NAME(IID_IPropertySetStorage) }, 279 { ID_NAME(IID_IPropertyStore) }, 280 { ID_NAME(IID_IPropSheetPage), TRUE }, 281 { ID_NAME(IID_IProvideClassInfo) }, 282 { ID_NAME(IID_IProvideClassInfo2) }, 283 { ID_NAME(IID_IQueryAssociations), TRUE }, 284 { ID_NAME(IID_IQueryCancelAutoPlay) }, 285 { ID_NAME(IID_IQueryInfo), TRUE }, 286 { ID_NAME(IID_IQuickActivate) }, 287 { ID_NAME(IID_IRegTreeOptions), TRUE }, 288 { ID_NAME(IID_IRemoteComputer) }, 289 { ID_NAME(IID_IResolveShellLink) }, 290 { ID_NAME(IID_IROTData), }, 291 { ID_NAME(IID_IRpcOptions), TRUE }, 292 { ID_NAME(IID_IRunnableObject) }, 293 { ID_NAME(IID_IRunningObjectTable), }, 294 { ID_NAME(IID_ISLTracker), TRUE }, 295 { ID_NAME(IID_IScriptErrorList) }, 296 { ID_NAME(IID_ISearch) }, 297 { ID_NAME(IID_ISearchAssistantOC) }, 298 { ID_NAME(IID_ISearchAssistantOC2) }, 299 { ID_NAME(IID_ISearchAssistantOC3) }, 300 { ID_NAME(IID_ISearchBar) }, 301 { ID_NAME(IID_ISearches) }, 302 { ID_NAME(IID_ISecMgrCacheSeedTarget) }, 303 { ID_NAME(IID_IServerSecurity), TRUE }, 304 { ID_NAME(IID_IServiceProvider) }, 305 { ID_NAME(IID_IShellApp), TRUE }, 306 { ID_NAME(IID_IShellBrowser) }, 307 { ID_NAME(IID_IShellBrowserService), TRUE }, 308 { ID_NAME(IID_IShellChangeNotify), TRUE }, 309 { ID_NAME(IID_IShellCopyHookA), TRUE }, 310 { ID_NAME(IID_IShellCopyHookW), TRUE }, 311 { ID_NAME(IID_IShellDesktopTray), TRUE }, 312 { ID_NAME(IID_IShellDetails), TRUE }, 313 { ID_NAME(IID_IShellDispatch) }, 314 { ID_NAME(IID_IShellDispatch2) }, 315 { ID_NAME(IID_IShellDispatch3) }, 316 { ID_NAME(IID_IShellDispatch4) }, 317 { ID_NAME(IID_IShellDispatch5), TRUE }, 318 { ID_NAME(IID_IShellDispatch6), TRUE }, 319 { ID_NAME(IID_IShellExecuteHookA), TRUE }, 320 { ID_NAME(IID_IShellExecuteHookW), TRUE }, 321 { ID_NAME(IID_IShellExtInit), TRUE }, 322 { ID_NAME(IID_IShellFavoritesNameSpace) }, 323 { ID_NAME(IID_IShellFolder) }, 324 { ID_NAME(IID_IShellFolder2) }, 325 { ID_NAME(IID_IShellFolderBand), TRUE }, 326 { ID_NAME(IID_IShellFolderSearchable), TRUE }, 327 { ID_NAME(IID_IShellFolderSearchableCallback), TRUE }, 328 { ID_NAME(IID_IShellFolderView), TRUE }, 329 { ID_NAME(IID_IShellFolderViewCB), TRUE }, 330 { ID_NAME(IID_IShellFolderViewDual) }, 331 { ID_NAME(IID_IShellFolderViewDual2) }, 332 { ID_NAME(IID_IShellFolderViewDual3), TRUE }, 333 { ID_NAME(IID_IShellFolderViewType), TRUE }, 334 { ID_NAME(IID_IShellIcon) }, 335 { ID_NAME(IID_IShellIconOverlay), TRUE }, 336 { ID_NAME(IID_IShellIconOverlayIdentifier), TRUE }, 337 { ID_NAME(IID_IShellImageData), TRUE }, 338 { ID_NAME(IID_IShellImageDataAbort), TRUE }, 339 { ID_NAME(IID_IShellImageDataFactory), TRUE }, 340 { ID_NAME(IID_IShellItem) }, 341 { ID_NAME(IID_IShellItem2) }, 342 { ID_NAME(IID_IShellItemArray) }, 343 { ID_NAME(IID_IShellItemFilter) }, 344 { ID_NAME(IID_IShellLinkA) }, 345 { ID_NAME(IID_IShellLinkDataList), TRUE }, 346 { ID_NAME(IID_IShellLinkDual) }, 347 { ID_NAME(IID_IShellLinkDual2) }, 348 { ID_NAME(IID_IShellLinkW) }, 349 { ID_NAME(IID_IShellMenu), TRUE }, 350 { ID_NAME(IID_IShellMenu2), TRUE }, 351 { ID_NAME(IID_IShellMenuAcc), TRUE }, 352 { ID_NAME(IID_IShellMenuCallback), TRUE }, 353 { ID_NAME(IID_IShellNameSpace) }, 354 { ID_NAME(IID_IShellPropSheetExt), TRUE }, 355 { ID_NAME(IID_IShellService), TRUE }, 356 { ID_NAME(IID_IShellTaskScheduler), TRUE }, 357 { ID_NAME(IID_IShellUIHelper) }, 358 { ID_NAME(IID_IShellUIHelper2), TRUE }, 359 { ID_NAME(IID_IShellView) }, 360 { ID_NAME(IID_IShellView2) }, 361 { ID_NAME(IID_IShellView3) }, 362 { ID_NAME(IID_IShellWindows) }, 363 { ID_NAME(IID_ISpecifyPropertyPages) }, 364 { ID_NAME(IID_IStorage) }, 365 { ID_NAME(IID_IStream) }, 366 { ID_NAME(IID_ISurrogate) }, 367 { ID_NAME(IID_ISynchronize) }, 368 { ID_NAME(IID_ISynchronizeContainer), TRUE }, 369 { ID_NAME(IID_ISynchronizeEvent), TRUE }, 370 { ID_NAME(IID_ISynchronizeHandle), TRUE }, 371 { ID_NAME(IID_ITargetEmbedding) }, 372 { ID_NAME(IID_ITargetFrame) }, 373 { ID_NAME(IID_ITargetFrame2) }, 374 { ID_NAME(IID_ITargetFramePriv) }, 375 { ID_NAME(IID_ITargetFramePriv2) }, 376 { ID_NAME(IID_ITargetNotify) }, 377 { ID_NAME(IID_ITaskbarList) }, 378 { ID_NAME(IID_ITaskbarList2) }, 379 { ID_NAME(IID_ITaskbarList3), TRUE }, 380 { ID_NAME(IID_ITaskbarList4), TRUE }, 381 { ID_NAME(IID_ITrackShellMenu), TRUE }, 382 /* This interface is completely different between PSDK and registry/shell32 */ 383 { ID_NAME(IID_ITransferAdviseSink), TRUE }, 384 #define IID_ITransferAdviseSink IID_ITransferAdviseSinkPriv 385 { ID_NAME(IID_ITransferAdviseSink) }, 386 #undef IID_ITransferAdviseSink 387 { ID_NAME(IID_ITransferDestination), TRUE }, 388 { ID_NAME(IID_ITransferSource), TRUE }, 389 { ID_NAME(IID_ITranslateShellChangeNotify), TRUE }, 390 { ID_NAME(IID_ITrayPriv), TRUE }, 391 { ID_NAME(IID_ITrayPriv2), TRUE }, 392 { ID_NAME(IID_IUnknown) }, 393 { ID_NAME(IID_IURLSearchHook), TRUE }, 394 { ID_NAME(IID_IURLSearchHook2), TRUE }, 395 { ID_NAME(IID_IUrlHistoryNotify) }, 396 { ID_NAME(IID_IUrlHistoryStg) }, 397 { ID_NAME(IID_IUrlHistoryStg2) }, 398 { ID_NAME(IID_IViewObject) }, 399 { ID_NAME(IID_IViewObject2) }, 400 { ID_NAME(IID_IViewObjectEx), TRUE }, 401 { ID_NAME(IID_IVisualProperties) }, 402 { ID_NAME(IID_IWebBrowser) }, 403 { ID_NAME(IID_IWebBrowser2) }, 404 { ID_NAME(IID_IWebBrowserApp) }, 405 { ID_NAME(IID_IWebBrowserPriv) }, 406 { ID_NAME(IID_IWebBrowserPriv2) }, 407 { ID_NAME(IID_IWinEventHandler), TRUE }, 408 409 { ID_NAME(IID_DFConstraint), TRUE }, 410 { ID_NAME(DIID__SearchAssistantEvents) }, 411 { ID_NAME(DIID_DShellFolderViewEvents) }, 412 { ID_NAME(DIID_DShellNameSpaceEvents) }, 413 { ID_NAME(DIID_DShellWindowsEvents) }, 414 { ID_NAME(DIID_DWebBrowserEvents) }, 415 { ID_NAME(DIID_DWebBrowserEvents2) }, 416 { ID_NAME(DIID_XMLDOMDocumentEvents ) }, 417 418 { ID_NAME(IID_CDefView), TRUE }, 419 { ID_NAME(IID_Folder) }, 420 { ID_NAME(IID_Folder2) }, 421 { ID_NAME(IID_Folder3) }, 422 { ID_NAME(IID_FolderItem) }, 423 { ID_NAME(IID_FolderItem2) }, 424 { ID_NAME(IID_FolderItems) }, 425 { ID_NAME(IID_FolderItems2) }, 426 { ID_NAME(IID_FolderItems3) }, 427 { ID_NAME(IID_FolderItemVerb) }, 428 { ID_NAME(IID_FolderItemVerbs) }, 429 430 { ID_NAME(CLSID_ShellDesktop), TRUE }, 431 432 { ID_NAME(IID_IQueryContinue) }, 433 { ID_NAME(IID_IUserNotification) }, 434 { ID_NAME(IID_IUserNotificationCallback) }, // On Vista+ 435 { ID_NAME(IID_IUserNotification2) }, // On Vista+ 436 437 { ID_NAME(IID_IAggregateFilterCondition) }, 438 { ID_NAME(IID_IAliasRegistrationCallback), TRUE }, 439 { ID_NAME(IID_IAssociationArrayInitialize), TRUE }, 440 { ID_NAME(IID_IAssociationList), TRUE }, 441 { ID_NAME(IID_IBackReferencedObject), TRUE }, 442 { ID_NAME(IID_IBasePropPage), TRUE }, 443 { ID_NAME(IID_ICommonLayoutDefinition), TRUE }, 444 { ID_NAME(IID_IControlPanelEnumerator), TRUE }, 445 { ID_NAME(IID_IDelegateHostItemContainer), TRUE }, 446 { ID_NAME(IID_IDrawPropertyControl), TRUE }, 447 { ID_NAME(IID_IEnumAssociationElements), TRUE }, 448 { ID_NAME(IID_IEnumerateAssociationElements),TRUE }, 449 { ID_NAME(IID_IExecuteCommand), TRUE }, 450 { ID_NAME(IID_IFilterCondition) }, 451 { ID_NAME(IID_IFolderNotify), TRUE }, 452 { ID_NAME(IID_IFolderProperties), TRUE }, 453 { ID_NAME(IID_IFolderType), TRUE }, 454 { ID_NAME(IID_IFolderWithSearchRoot), TRUE }, 455 { ID_NAME(IID_IFrameLayoutDefinition), TRUE }, 456 { ID_NAME(IID_IItemFilter), TRUE }, 457 { ID_NAME(IID_IItemFilterOwner), TRUE }, 458 { ID_NAME(IID_ILocalizableItemParent), TRUE }, 459 { ID_NAME(IID_INewItemAdvisor), TRUE }, 460 { ID_NAME(IID_IObjectWithAssociationElement),TRUE }, 461 { ID_NAME(IID_IObjectWithAssociationList), TRUE }, 462 { ID_NAME(IID_IObjectWithQuerySource), TRUE }, 463 { ID_NAME(IID_IObjectWithSelection), TRUE }, 464 { ID_NAME(IID_IPersistString2), TRUE }, 465 { ID_NAME(IID_IPrinterFolder), TRUE }, 466 { ID_NAME(IID_IPropertyControl), TRUE }, 467 { ID_NAME(IID_IPropertyControlBase), TRUE }, 468 { ID_NAME(IID_IPropertyControlSite), TRUE }, 469 { ID_NAME(IID_IRegItemCustomAttributes), TRUE }, 470 { ID_NAME(IID_IRegItemCustomEnumerator), TRUE }, 471 { ID_NAME(IID_IRegItemFolder), TRUE }, 472 { ID_NAME(IID_IRootAndRelativeParsingFolder),TRUE }, 473 { ID_NAME(IID_IScope), TRUE }, 474 { ID_NAME(IID_IScopeItem), TRUE }, 475 { ID_NAME(IID_IShellBrowserServce), TRUE }, 476 { ID_NAME(IID_IShellFolder3), TRUE }, 477 { ID_NAME(IID_ITaskCondition), TRUE }, 478 { ID_NAME(IID_ITaskConditionCombiner), TRUE }, 479 { ID_NAME(IID_ITaskConditionInit), TRUE }, 480 { ID_NAME(IID_ITransferProvider), TRUE }, 481 { ID_NAME(IID_IUserEventTimer) }, 482 { ID_NAME(IID_IUserEventTimerCallback) }, 483 { ID_NAME(IID_IAssociationArrayOld), TRUE }, 484 { ID_NAME(IID_IAssociationArray), TRUE }, 485 #define IID_IDriveFolderExt IID_IDriveFolderExtOld 486 { ID_NAME(IID_IDriveFolderExt) }, 487 #undef IID_IDriveFolderExt 488 { ID_NAME(IID_IPinnedListOld), TRUE }, 489 { ID_NAME(IID_IPinnedList), TRUE }, 490 { ID_NAME(IID_IAttachmentExecute), TRUE }, 491 }; 492 static const INT KnownInterfaceCount = RTL_NUMBER_OF(KnownInterfaces); 493 494 static 495 PCKNOWN_INTERFACE 496 FindInterface( 497 _In_ const IID *iid) 498 { 499 INT i; 500 501 for (i = 0; i < KnownInterfaceCount; i++) 502 if (IsEqualIID(KnownInterfaces[i].iid, iid)) 503 return &KnownInterfaces[i]; 504 ASSERT(i != KnownInterfaceCount); 505 return NULL; 506 } 507 508 static 509 BOOLEAN 510 IsInterfaceExpected( 511 _In_ PCCLASS_AND_INTERFACES class, 512 _In_ const IID *iid) 513 { 514 INT i; 515 516 for (i = 0; class->ifaces[i].iid; i++) 517 if (IsEqualIID(class->ifaces[i].iid, iid)) 518 return TRUE; 519 return FALSE; 520 } 521 522 #define INTF_NOT_EXPOSED LONG_MAX 523 static 524 LONG 525 GetInterfaceOffset( 526 _In_ PUNKNOWN pUnk, 527 _In_ const IID *iid) 528 { 529 HRESULT hr; 530 PVOID pObj; 531 PUNKNOWN pUnk2; 532 LONG offset; 533 534 hr = IUnknown_QueryInterface(pUnk, iid, &pObj); 535 ok(hr == S_OK || hr == E_NOINTERFACE, "IUnknown::QueryInterface returned 0x%lx\n", hr); 536 if (FAILED(hr)) 537 return INTF_NOT_EXPOSED; 538 539 pUnk2 = pObj; 540 offset = (LONG_PTR)pObj - (LONG_PTR)pUnk; 541 IUnknown_Release(pUnk2); 542 return offset; 543 } 544 545 static 546 VOID 547 TestModuleInterfaces( 548 _In_ PCCLASS_AND_INTERFACES ExpectedInterfaces, 549 _In_ INT ExpectedInterfaceCount) 550 { 551 HRESULT hr; 552 PVOID pObj; 553 PUNKNOWN pUnk; 554 INT iClass, iIntf; 555 PCCLASS_AND_INTERFACES class; 556 557 for (iClass = 0; iClass < ExpectedInterfaceCount; iClass++) 558 { 559 class = &ExpectedInterfaces[iClass]; 560 hr = CoCreateInstance(class->clsid, 561 NULL, 562 CLSCTX_INPROC_SERVER, 563 &IID_IUnknown, 564 &pObj); 565 ok(hr == S_OK, "CoCreateInstance failed. hr=0x%lx\n", hr); 566 if (FAILED(hr)) 567 { 568 skip("Failed to instantiate %s.\n", class->name); 569 continue; 570 } 571 572 pUnk = pObj; 573 574 /* Check that all expected interfaces are present and have the right offset */ 575 for (iIntf = 0; class->ifaces[iIntf].iid; iIntf++) 576 { 577 PCKNOWN_INTERFACE iface = FindInterface(class->ifaces[iIntf].iid); 578 LONG offset = GetInterfaceOffset(pUnk, iface->iid); 579 if (offset == INTF_NOT_EXPOSED) 580 ok(0, "%s is missing %s (offset %ld)\n", class->name, iface->name, class->ifaces[iIntf].offset); 581 else if (class->ifaces[iIntf].offset != FARAWY) 582 { 583 #ifdef FAIL_WRONG_OFFSET 584 ok(offset == class->ifaces[iIntf].offset, "%s, %s offset is %ld, expected %ld\n", class->name, iface->name, offset, class->ifaces[iIntf].offset); 585 #else 586 if (offset != class->ifaces[iIntf].offset) 587 mytrace("%s, %s offset is %ld, expected %ld\n", class->name, iface->name, offset, class->ifaces[iIntf].offset); 588 #endif 589 } 590 } 591 592 /* Check that none other than the expected interfaces are present */ 593 for (iIntf = 0; iIntf < KnownInterfaceCount; iIntf++) 594 { 595 PCKNOWN_INTERFACE iface = &KnownInterfaces[iIntf]; 596 LONG offset; 597 if (IsInterfaceExpected(class, iface->iid)) 598 continue; 599 offset = GetInterfaceOffset(pUnk, iface->iid); 600 #ifdef GENERATE_TABLE_ENTRIES 601 ok(offset == INTF_NOT_EXPOSED, "%s: { %s0x%lx, &%s },\n", class->name, offset < 0 ? "-" : "", offset < 0 ? -offset : offset, iface->name); 602 #else 603 ok(offset == INTF_NOT_EXPOSED, "%s exposes %s (offset %ld), but shouldn't\n", class->name, iface->name, offset); 604 #endif 605 } 606 607 // TODO: do some aggregation 608 609 IUnknown_Release(pUnk); 610 } 611 } 612 613 static 614 VOID 615 TestModuleRegistry( 616 _In_ PCWSTR ModuleName, 617 _In_ PCCLASS_AND_INTERFACES ExpectedInterfaces, 618 _In_ INT ExpectedInterfaceCount) 619 { 620 INT iClass; 621 PCCLASS_AND_INTERFACES class; 622 HKEY hKeyClasses; 623 LONG result; 624 625 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID", 0, KEY_ENUMERATE_SUB_KEYS, &hKeyClasses); 626 ok(result == NO_ERROR, "Failed to open classes key, error %lu\n", result); 627 if (!myskip(result == NO_ERROR, "No classes key\n")) 628 { 629 for (iClass = 0; iClass < ExpectedInterfaceCount; iClass++) 630 { 631 HKEY hKey; 632 HKEY hKeyServer; 633 NTSTATUS status; 634 UNICODE_STRING clsid; 635 DWORD type; 636 WCHAR data[100]; 637 DWORD dataSize; 638 PCWSTR expectedThreadingModel; 639 640 class = &ExpectedInterfaces[iClass]; 641 status = RtlStringFromGUID(class->clsid, &clsid); 642 ok(status == STATUS_SUCCESS, "Failed to convert guid to string for %s, status %lx\n", class->name, status); 643 if (myskip(NT_SUCCESS(status), "No guid string\n")) 644 continue; 645 646 result = RegOpenKeyExW(hKeyClasses, clsid.Buffer, 0, KEY_ENUMERATE_SUB_KEYS, &hKey); 647 ok(result == NO_ERROR, "Failed to open key for %s, error %lu\n", class->name, result); 648 RtlFreeUnicodeString(&clsid); 649 if (myskip(result == NO_ERROR, "No key\n")) 650 continue; 651 652 result = RegOpenKeyExW(hKey, L"InProcServer32", 0, KEY_QUERY_VALUE, &hKeyServer); 653 ok(result == NO_ERROR, "Failed to open key for %s, error %lu\n", class->name, result); 654 RegCloseKey(hKey); 655 if (myskip(result == NO_ERROR, "No key\n")) 656 continue; 657 658 dataSize = sizeof(data); 659 result = RegQueryValueExW(hKeyServer, NULL, NULL, &type, (PBYTE)data, &dataSize); 660 ok(result == NO_ERROR, "Failed to query value for %s, error %lu\n", class->name, result); 661 if (!myskip(result == NO_ERROR, "No module name\n")) 662 { 663 ok(type == REG_SZ || type == REG_EXPAND_SZ, "type %lu for %s\n", type, class->name); 664 ok(dataSize % sizeof(WCHAR) == 0, "size %lu for %s\n", dataSize, class->name); 665 ok(dataSize <= sizeof(data), "size %lu for %s\n", dataSize, class->name); 666 ok(data[dataSize / sizeof(WCHAR) - 1] == UNICODE_NULL, "Not null terminated for %s\n", class->name); 667 // TODO: Use SearchPath (or assume everything's in system32) and do a proper full path compare 668 PathStripPathW(data); 669 PathRemoveExtensionW(data); 670 ok(!wcsicmp(data, ModuleName), "Server is %ls, expected %ls for %s\n", data, ModuleName, class->name); 671 } 672 673 dataSize = sizeof(data); 674 result = RegQueryValueExW(hKeyServer, L"ThreadingModel", NULL, &type, (PBYTE)data, &dataSize); 675 ok(result == NO_ERROR, "Failed to query value for %s, error %lu\n", class->name, result); 676 if (!myskip(result == NO_ERROR, "No ThreadingModel\n")) 677 { 678 ok(type == REG_SZ || type == REG_EXPAND_SZ, "type %lu for %s\n", type, class->name); 679 ok(dataSize % sizeof(WCHAR) == 0, "size %lu for %s\n", dataSize, class->name); 680 ok(dataSize <= sizeof(data), "size %lu for %s\n", dataSize, class->name); 681 ok(data[dataSize / sizeof(WCHAR) - 1] == UNICODE_NULL, "Not null terminated for %s\n", class->name); 682 expectedThreadingModel = class->ThreadingModel; 683 if (!expectedThreadingModel) 684 expectedThreadingModel = L"Apartment"; 685 ok(!wcsicmp(data, expectedThreadingModel), "Server is %ls, expected %ls for %s\n", data, expectedThreadingModel, class->name); 686 } 687 688 RegCloseKey(hKeyServer); 689 } 690 RegCloseKey(hKeyClasses); 691 } 692 } 693 694 static 695 VOID 696 TestManualInstantiation( 697 _In_ PCWSTR ModuleName, 698 _In_ PCCLASS_AND_INTERFACES ExpectedInterfaces, 699 _In_ INT ExpectedInterfaceCount) 700 { 701 INT iClass; 702 PCCLASS_AND_INTERFACES class; 703 HRESULT (__stdcall *DllGetClassObject)(REFCLSID, REFIID, PVOID *); 704 705 DllGetClassObject = (PVOID)GetProcAddress(GetModuleHandleW(ModuleName), "DllGetClassObject"); 706 ok(DllGetClassObject != NULL, "DllGetClassObject not found in %ls, error %lu\n", ModuleName, GetLastError()); 707 if (myskip(DllGetClassObject != NULL, "No DllGetClassObject\n")) 708 return; 709 710 for (iClass = 0; iClass < ExpectedInterfaceCount; iClass++) 711 { 712 PVOID pv; 713 HRESULT hr; 714 class = &ExpectedInterfaces[iClass]; 715 hr = DllGetClassObject(class->clsid, &IID_IClassFactory, &pv); 716 ok(hr == S_OK, "DllGetClassObject failed for %s, hr = 0x%lx\n", class->name, hr); 717 if (!myskip(SUCCEEDED(hr), "No class factory\n")) 718 { 719 IClassFactory *pCF = pv; 720 hr = IClassFactory_CreateInstance(pCF, NULL, &IID_IUnknown, &pv); 721 ok(hr == S_OK, "IClassFactory::CreateInstance failed for %s, hr = 0x%lx\n", class->name, hr); 722 if (!myskip(SUCCEEDED(hr), "No instance\n")) 723 { 724 IUnknown *pUnk = pv; 725 IUnknown_Release(pUnk); 726 } 727 IClassFactory_Release(pCF); 728 } 729 } 730 } 731 732 VOID 733 TestClasses( 734 _In_ PCWSTR ModuleName, 735 _In_ PCCLASS_AND_INTERFACES ExpectedInterfaces, 736 _In_ INT ExpectedInterfaceCount) 737 { 738 HRESULT hr; 739 740 hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); 741 ok(hr == S_OK, "CoInitializeEx failed. hr=0x%lx\n", hr); 742 if (myskip(SUCCEEDED(hr), "Failed to initialize COM. Cannot perform tests\n")) 743 return; 744 745 TestModuleInterfaces(ExpectedInterfaces, ExpectedInterfaceCount); 746 TestModuleRegistry(ModuleName, ExpectedInterfaces, ExpectedInterfaceCount); 747 TestManualInstantiation(ModuleName, ExpectedInterfaces, ExpectedInterfaceCount); 748 749 CoUninitialize(); 750 } 751 752 static 753 VOID 754 TestInterfaceRegistry( 755 _In_ PCKNOWN_INTERFACE Interfaces, 756 _In_ INT InterfaceCount) 757 { 758 INT i; 759 HKEY hKeyInterface; 760 LONG result; 761 762 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Classes\\Interface", 0, KEY_ENUMERATE_SUB_KEYS, &hKeyInterface); 763 ok(result == NO_ERROR, "Failed to open interface key, error %lu\n", result); 764 if (!myskip(result == NO_ERROR, "No interface key\n")) 765 { 766 for (i = 0; i < InterfaceCount; i++) 767 { 768 HKEY hKey; 769 NTSTATUS status; 770 UNICODE_STRING iid; 771 DWORD type; 772 WCHAR data[100]; 773 DWORD dataSize; 774 PCKNOWN_INTERFACE iface; 775 PCWSTR expectedName; 776 777 iface = &Interfaces[i]; 778 status = RtlStringFromGUID(iface->iid, &iid); 779 ok(status == STATUS_SUCCESS, "Failed to convert guid to string for %s, status %lx\n", iface->name, status); 780 if (myskip(NT_SUCCESS(status), "No guid string\n")) 781 continue; 782 783 result = RegOpenKeyExW(hKeyInterface, iid.Buffer, 0, KEY_QUERY_VALUE, &hKey); 784 if (iface->noreg) 785 { 786 ok(result == ERROR_FILE_NOT_FOUND, "RegOpenKeyEx returned %lu for %s\n", result, iface->name); 787 } 788 else 789 { 790 ok(result == NO_ERROR, "Failed to open key for %s, error %lu\n", iface->name, result); 791 (void)myskip(result == NO_ERROR, "No key\n"); 792 } 793 RtlFreeUnicodeString(&iid); 794 if (result != NO_ERROR) 795 continue; 796 797 dataSize = sizeof(data); 798 result = RegQueryValueExW(hKey, NULL, NULL, &type, (PBYTE)data, &dataSize); 799 ok(result == NO_ERROR, "Failed to query value for %s, error %lu\n", iface->name, result); 800 if (!myskip(result == NO_ERROR, "No module name\n")) 801 { 802 ok(type == REG_SZ, "type %lu for %s\n", type, iface->name); 803 ok(dataSize % sizeof(WCHAR) == 0, "size %lu for %s\n", dataSize, iface->name); 804 ok(dataSize <= sizeof(data), "size %lu for %s\n", dataSize, iface->name); 805 ok(data[dataSize / sizeof(WCHAR) - 1] == UNICODE_NULL, "Not null terminated for %s\n", iface->name); 806 expectedName = wcschr(iface->wname, L'_'); 807 if (expectedName) 808 expectedName++; 809 else 810 expectedName = iface->wname; 811 ok(!wcsicmp(data, expectedName), "Name is %ls, expected %ls\n", data, expectedName); 812 } 813 814 RegCloseKey(hKey); 815 } 816 RegCloseKey(hKeyInterface); 817 } 818 } 819 820 START_TEST(interfaces) 821 { 822 TestInterfaceRegistry(KnownInterfaces, KnownInterfaceCount); 823 } 824