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 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 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 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 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 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 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 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 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 841 START_TEST(interfaces) 842 { 843 TestInterfaceRegistry(KnownInterfaces, KnownInterfaceCount); 844 } 845