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 // + MMC stuff 493 { ID_NAME(IID_IComponentData), TRUE }, 494 { ID_NAME(IID_IConsole), TRUE }, 495 { ID_NAME(IID_IConsole2), TRUE }, 496 { ID_NAME(IID_IConsoleNameSpace), TRUE }, 497 { ID_NAME(IID_IConsoleNameSpace2), TRUE }, 498 { ID_NAME(IID_IPropertySheetCallback), TRUE }, 499 { ID_NAME(IID_IPropertySheetProvider), TRUE }, 500 { ID_NAME(IID_IExtendPropertySheet), TRUE }, 501 { ID_NAME(IID_IExtendPropertySheet2), TRUE }, 502 { ID_NAME(IID_IHeaderCtrl), TRUE }, 503 { ID_NAME(IID_IToolbar), TRUE }, 504 { ID_NAME(IID_IImageList_mmc), TRUE }, 505 { ID_NAME(IID_IConsoleVerb), TRUE }, 506 { ID_NAME(IID_ISnapInAbout), TRUE }, 507 // - MMC stuff 508 509 { ID_NAME(IID_ICertificateManager), TRUE }, 510 }; 511 static const INT KnownInterfaceCount = RTL_NUMBER_OF(KnownInterfaces); 512 513 static 514 PCKNOWN_INTERFACE 515 FindInterface( 516 _In_ const IID *iid) 517 { 518 INT i; 519 520 for (i = 0; i < KnownInterfaceCount; i++) 521 if (IsEqualIID(KnownInterfaces[i].iid, iid)) 522 return &KnownInterfaces[i]; 523 ASSERT(i != KnownInterfaceCount); 524 return NULL; 525 } 526 527 static 528 BOOLEAN 529 IsInterfaceExpected( 530 _In_ PCCLASS_AND_INTERFACES class, 531 _In_ const IID *iid) 532 { 533 INT i; 534 535 for (i = 0; class->ifaces[i].iid; i++) 536 if (IsEqualIID(class->ifaces[i].iid, iid)) 537 return TRUE; 538 return FALSE; 539 } 540 541 #define INTF_NOT_EXPOSED LONG_MAX 542 static 543 LONG 544 GetInterfaceOffset( 545 _In_ PUNKNOWN pUnk, 546 _In_ const IID *iid) 547 { 548 HRESULT hr; 549 PVOID pObj; 550 PUNKNOWN pUnk2; 551 LONG offset; 552 553 hr = IUnknown_QueryInterface(pUnk, iid, &pObj); 554 ok(hr == S_OK || hr == E_NOINTERFACE, "IUnknown::QueryInterface returned 0x%lx\n", hr); 555 if (FAILED(hr)) 556 return INTF_NOT_EXPOSED; 557 558 pUnk2 = pObj; 559 offset = (LONG_PTR)pObj - (LONG_PTR)pUnk; 560 IUnknown_Release(pUnk2); 561 return offset; 562 } 563 564 static 565 VOID 566 TestModuleInterfaces( 567 _In_ PCCLASS_AND_INTERFACES ExpectedInterfaces, 568 _In_ INT ExpectedInterfaceCount) 569 { 570 HRESULT hr; 571 PVOID pObj; 572 PUNKNOWN pUnk; 573 INT iClass, iIntf; 574 PCCLASS_AND_INTERFACES class; 575 576 for (iClass = 0; iClass < ExpectedInterfaceCount; iClass++) 577 { 578 class = &ExpectedInterfaces[iClass]; 579 hr = CoCreateInstance(class->clsid, 580 NULL, 581 CLSCTX_INPROC_SERVER, 582 &IID_IUnknown, 583 &pObj); 584 ok(hr == S_OK, "CoCreateInstance failed. hr=0x%lx\n", hr); 585 if (FAILED(hr)) 586 { 587 skip("Failed to instantiate %s.\n", class->name); 588 continue; 589 } 590 591 pUnk = pObj; 592 593 /* Check that all expected interfaces are present and have the right offset */ 594 for (iIntf = 0; class->ifaces[iIntf].iid; iIntf++) 595 { 596 PCKNOWN_INTERFACE iface = FindInterface(class->ifaces[iIntf].iid); 597 LONG offset = GetInterfaceOffset(pUnk, iface->iid); 598 if (offset == INTF_NOT_EXPOSED) 599 ok(0, "%s is missing %s (offset %ld)\n", class->name, iface->name, class->ifaces[iIntf].offset); 600 else if (class->ifaces[iIntf].offset != FARAWY) 601 { 602 #ifdef FAIL_WRONG_OFFSET 603 ok(offset == class->ifaces[iIntf].offset, "%s, %s offset is %ld, expected %ld\n", class->name, iface->name, offset, class->ifaces[iIntf].offset); 604 #else 605 if (offset != class->ifaces[iIntf].offset) 606 mytrace("%s, %s offset is %ld, expected %ld\n", class->name, iface->name, offset, class->ifaces[iIntf].offset); 607 #endif 608 } 609 } 610 611 /* Check that none other than the expected interfaces are present */ 612 for (iIntf = 0; iIntf < KnownInterfaceCount; iIntf++) 613 { 614 PCKNOWN_INTERFACE iface = &KnownInterfaces[iIntf]; 615 LONG offset; 616 if (IsInterfaceExpected(class, iface->iid)) 617 continue; 618 offset = GetInterfaceOffset(pUnk, iface->iid); 619 #ifdef GENERATE_TABLE_ENTRIES 620 ok(offset == INTF_NOT_EXPOSED, "%s: { %s0x%lx, &%s },\n", class->name, offset < 0 ? "-" : "", offset < 0 ? -offset : offset, iface->name); 621 #else 622 ok(offset == INTF_NOT_EXPOSED, "%s exposes %s (offset %ld), but shouldn't\n", class->name, iface->name, offset); 623 #endif 624 } 625 626 // TODO: do some aggregation 627 628 IUnknown_Release(pUnk); 629 } 630 } 631 632 static 633 VOID 634 TestModuleRegistry( 635 _In_ PCWSTR ModuleName, 636 _In_ PCCLASS_AND_INTERFACES ExpectedInterfaces, 637 _In_ INT ExpectedInterfaceCount) 638 { 639 INT iClass; 640 PCCLASS_AND_INTERFACES class; 641 HKEY hKeyClasses; 642 LONG result; 643 644 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID", 0, KEY_ENUMERATE_SUB_KEYS, &hKeyClasses); 645 ok(result == NO_ERROR, "Failed to open classes key, error %lu\n", result); 646 if (!myskip(result == NO_ERROR, "No classes key\n")) 647 { 648 for (iClass = 0; iClass < ExpectedInterfaceCount; iClass++) 649 { 650 HKEY hKey; 651 HKEY hKeyServer; 652 NTSTATUS status; 653 UNICODE_STRING clsid; 654 DWORD type; 655 WCHAR data[100]; 656 DWORD dataSize; 657 PCWSTR expectedThreadingModel; 658 659 class = &ExpectedInterfaces[iClass]; 660 status = RtlStringFromGUID(class->clsid, &clsid); 661 ok(status == STATUS_SUCCESS, "Failed to convert guid to string for %s, status %lx\n", class->name, status); 662 if (myskip(NT_SUCCESS(status), "No guid string\n")) 663 continue; 664 665 result = RegOpenKeyExW(hKeyClasses, clsid.Buffer, 0, KEY_ENUMERATE_SUB_KEYS, &hKey); 666 ok(result == NO_ERROR, "Failed to open key for %s, error %lu\n", class->name, result); 667 RtlFreeUnicodeString(&clsid); 668 if (myskip(result == NO_ERROR, "No key\n")) 669 continue; 670 671 result = RegOpenKeyExW(hKey, L"InProcServer32", 0, KEY_QUERY_VALUE, &hKeyServer); 672 ok(result == NO_ERROR, "Failed to open key for %s, error %lu\n", class->name, result); 673 RegCloseKey(hKey); 674 if (myskip(result == NO_ERROR, "No key\n")) 675 continue; 676 677 dataSize = sizeof(data); 678 result = RegQueryValueExW(hKeyServer, NULL, NULL, &type, (PBYTE)data, &dataSize); 679 ok(result == NO_ERROR, "Failed to query value for %s, error %lu\n", class->name, result); 680 if (!myskip(result == NO_ERROR, "No module name\n")) 681 { 682 ok(type == REG_SZ || type == REG_EXPAND_SZ, "type %lu for %s\n", type, class->name); 683 ok(dataSize % sizeof(WCHAR) == 0, "size %lu for %s\n", dataSize, class->name); 684 ok(dataSize <= sizeof(data), "size %lu for %s\n", dataSize, class->name); 685 ok(data[dataSize / sizeof(WCHAR) - 1] == UNICODE_NULL, "Not null terminated for %s\n", class->name); 686 // TODO: Use SearchPath (or assume everything's in system32) and do a proper full path compare 687 PathStripPathW(data); 688 PathRemoveExtensionW(data); 689 ok(!wcsicmp(data, ModuleName), "Server is %ls, expected %ls for %s\n", data, ModuleName, class->name); 690 } 691 692 dataSize = sizeof(data); 693 result = RegQueryValueExW(hKeyServer, L"ThreadingModel", NULL, &type, (PBYTE)data, &dataSize); 694 ok(result == NO_ERROR, "Failed to query value for %s, error %lu\n", class->name, result); 695 if (!myskip(result == NO_ERROR, "No ThreadingModel\n")) 696 { 697 ok(type == REG_SZ || type == REG_EXPAND_SZ, "type %lu for %s\n", type, class->name); 698 ok(dataSize % sizeof(WCHAR) == 0, "size %lu for %s\n", dataSize, class->name); 699 ok(dataSize <= sizeof(data), "size %lu for %s\n", dataSize, class->name); 700 ok(data[dataSize / sizeof(WCHAR) - 1] == UNICODE_NULL, "Not null terminated for %s\n", class->name); 701 expectedThreadingModel = class->ThreadingModel; 702 if (!expectedThreadingModel) 703 expectedThreadingModel = L"Apartment"; 704 ok(!wcsicmp(data, expectedThreadingModel), "Server is %ls, expected %ls for %s\n", data, expectedThreadingModel, class->name); 705 } 706 707 RegCloseKey(hKeyServer); 708 } 709 RegCloseKey(hKeyClasses); 710 } 711 } 712 713 static 714 VOID 715 TestManualInstantiation( 716 _In_ PCWSTR ModuleName, 717 _In_ PCCLASS_AND_INTERFACES ExpectedInterfaces, 718 _In_ INT ExpectedInterfaceCount) 719 { 720 INT iClass; 721 PCCLASS_AND_INTERFACES class; 722 HRESULT (__stdcall *DllGetClassObject)(REFCLSID, REFIID, PVOID *); 723 724 DllGetClassObject = (PVOID)GetProcAddress(GetModuleHandleW(ModuleName), "DllGetClassObject"); 725 ok(DllGetClassObject != NULL, "DllGetClassObject not found in %ls, error %lu\n", ModuleName, GetLastError()); 726 if (myskip(DllGetClassObject != NULL, "No DllGetClassObject\n")) 727 return; 728 729 for (iClass = 0; iClass < ExpectedInterfaceCount; iClass++) 730 { 731 PVOID pv; 732 HRESULT hr; 733 class = &ExpectedInterfaces[iClass]; 734 hr = DllGetClassObject(class->clsid, &IID_IClassFactory, &pv); 735 ok(hr == S_OK, "DllGetClassObject failed for %s, hr = 0x%lx\n", class->name, hr); 736 if (!myskip(SUCCEEDED(hr), "No class factory\n")) 737 { 738 IClassFactory *pCF = pv; 739 hr = IClassFactory_CreateInstance(pCF, NULL, &IID_IUnknown, &pv); 740 ok(hr == S_OK, "IClassFactory::CreateInstance failed for %s, hr = 0x%lx\n", class->name, hr); 741 if (!myskip(SUCCEEDED(hr), "No instance\n")) 742 { 743 IUnknown *pUnk = pv; 744 IUnknown_Release(pUnk); 745 } 746 IClassFactory_Release(pCF); 747 } 748 } 749 } 750 751 VOID 752 TestClasses( 753 _In_ PCWSTR ModuleName, 754 _In_ PCCLASS_AND_INTERFACES ExpectedInterfaces, 755 _In_ INT ExpectedInterfaceCount) 756 { 757 HRESULT hr; 758 759 hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); 760 ok(hr == S_OK, "CoInitializeEx failed. hr=0x%lx\n", hr); 761 if (myskip(SUCCEEDED(hr), "Failed to initialize COM. Cannot perform tests\n")) 762 return; 763 764 TestModuleInterfaces(ExpectedInterfaces, ExpectedInterfaceCount); 765 TestModuleRegistry(ModuleName, ExpectedInterfaces, ExpectedInterfaceCount); 766 TestManualInstantiation(ModuleName, ExpectedInterfaces, ExpectedInterfaceCount); 767 768 CoUninitialize(); 769 } 770 771 static 772 VOID 773 TestInterfaceRegistry( 774 _In_ PCKNOWN_INTERFACE Interfaces, 775 _In_ INT InterfaceCount) 776 { 777 INT i; 778 HKEY hKeyInterface; 779 LONG result; 780 781 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Classes\\Interface", 0, KEY_ENUMERATE_SUB_KEYS, &hKeyInterface); 782 ok(result == NO_ERROR, "Failed to open interface key, error %lu\n", result); 783 if (!myskip(result == NO_ERROR, "No interface key\n")) 784 { 785 for (i = 0; i < InterfaceCount; i++) 786 { 787 HKEY hKey; 788 NTSTATUS status; 789 UNICODE_STRING iid; 790 DWORD type; 791 WCHAR data[100]; 792 DWORD dataSize; 793 PCKNOWN_INTERFACE iface; 794 PCWSTR expectedName; 795 796 iface = &Interfaces[i]; 797 status = RtlStringFromGUID(iface->iid, &iid); 798 ok(status == STATUS_SUCCESS, "Failed to convert guid to string for %s, status %lx\n", iface->name, status); 799 if (myskip(NT_SUCCESS(status), "No guid string\n")) 800 continue; 801 802 result = RegOpenKeyExW(hKeyInterface, iid.Buffer, 0, KEY_QUERY_VALUE, &hKey); 803 if (iface->noreg) 804 { 805 ok(result == ERROR_FILE_NOT_FOUND, "RegOpenKeyEx returned %lu for %s\n", result, iface->name); 806 } 807 else 808 { 809 ok(result == NO_ERROR, "Failed to open key for %s, error %lu\n", iface->name, result); 810 (void)myskip(result == NO_ERROR, "No key\n"); 811 } 812 RtlFreeUnicodeString(&iid); 813 if (result != NO_ERROR) 814 continue; 815 816 dataSize = sizeof(data); 817 result = RegQueryValueExW(hKey, NULL, NULL, &type, (PBYTE)data, &dataSize); 818 ok(result == NO_ERROR, "Failed to query value for %s, error %lu\n", iface->name, result); 819 if (!myskip(result == NO_ERROR, "No module name\n")) 820 { 821 ok(type == REG_SZ, "type %lu for %s\n", type, iface->name); 822 ok(dataSize % sizeof(WCHAR) == 0, "size %lu for %s\n", dataSize, iface->name); 823 ok(dataSize <= sizeof(data), "size %lu for %s\n", dataSize, iface->name); 824 ok(data[dataSize / sizeof(WCHAR) - 1] == UNICODE_NULL, "Not null terminated for %s\n", iface->name); 825 expectedName = wcschr(iface->wname, L'_'); 826 if (expectedName) 827 expectedName++; 828 else 829 expectedName = iface->wname; 830 ok(!wcsicmp(data, expectedName), "Name is %ls, expected %ls\n", data, expectedName); 831 } 832 833 RegCloseKey(hKey); 834 } 835 RegCloseKey(hKeyInterface); 836 } 837 } 838 839 START_TEST(interfaces) 840 { 841 TestInterfaceRegistry(KnownInterfaces, KnownInterfaceCount); 842 } 843