static void test_CoGetClassObject(void) { IUnknown *pUnk = (IUnknown *)0xdeadbeef; HRESULT hr = CoGetClassObject(&CLSID_MyComputer, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk); ok(hr == CO_E_NOTINITIALIZED, "CoGetClassObject should have returned CO_E_NOTINITIALIZED instead of 0x%08lx\n", hr); ok(pUnk == NULL, "CoGetClassObject should have changed the passed in pointer to NULL, instead of %p\n", pUnk); hr = CoGetClassObject(&CLSID_MyComputer, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, NULL); ok(hr == E_INVALIDARG, "CoGetClassObject should have returned E_INVALIDARG instead of 0x%08lx\n", hr); }
HRESULT CreateStandaloneGame (void) { HRESULT hr; // Create the AdminSession class object IAdminSessionClassPtr spClass; if (!Error (hr = CoGetClassObject (__uuidof(AdminSession), CLSCTX_LOCAL_SERVER, NULL, __uuidof(spClass), (void**)&spClass))) { // Create an instance of the host object for an IAdminSessionHost interface AdminSessionSecureHost xHost; // Create an AdminSession object IAdminSessionPtr spSession; hr = spClass->CreateSession (&xHost, &spSession); ::CoDisconnectObject(&xHost, 0); if (!Error (hr)) { // Get the Server property from the session object IAdminServerPtr spServer; if (!Error (hr = spSession->get_Server (&spServer))) { // Get the Games property from the server object if (!Error (hr = spServer->get_Games (&m_spAdminGamesPtr))) { // check to see if there are existing games // and proceed only if there aren't CheckForExistingGames (); } } } } return hr; }
/****************************************************************************** * ClassMoniker_BindToObject ******************************************************************************/ static HRESULT WINAPI ClassMoniker_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult) { ClassMoniker *This = impl_from_IMoniker(iface); BIND_OPTS2 bindopts; IClassActivator *pActivator; HRESULT hr; TRACE("(%p,%p,%p,%p)\n", pbc, pmkToLeft, riid, ppvResult); bindopts.cbStruct = sizeof(bindopts); IBindCtx_GetBindOptions(pbc, (BIND_OPTS *)&bindopts); if (!pmkToLeft) return CoGetClassObject(&This->clsid, bindopts.dwClassContext, NULL, riid, ppvResult); else { hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IClassActivator, (void **)&pActivator); if (FAILED(hr)) return hr; hr = IClassActivator_GetClassObject(pActivator, &This->clsid, bindopts.dwClassContext, bindopts.locale, riid, ppvResult); IClassActivator_Release(pActivator); return hr; } }
bool IECrossfireBHO::initServer(bool startIfNeeded) { if (m_server) { return true; } if (!startIfNeeded && !FindWindow(ServerWindowClass, NULL)) { return false; } /* the following is intentionally commented */ // CComPtr<IDispatch> dispatch = NULL; // long applicationHwnd = 0; // HRESULT hr = m_webBrowser->get_Application(&dispatch); // if (SUCCEEDED(hr)) { // DISPID dispId; // CComBSTR name("HWND"); // hr = dispatch->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &dispId); // if (SUCCEEDED(hr)) { // DISPPARAMS params; // memset(¶ms, 0, sizeof(DISPPARAMS)); // VARIANT variant; // hr = dispatch->Invoke(dispId, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &variant, NULL, NULL); // if (SUCCEEDED(hr)) { // applicationHwnd = variant.lVal; // } // } // } // if (!applicationHwnd) { // Logger::error("IECrossfireBHO.initServer(): failed to get the application HWND", hr); // return false; // } CComPtr<ICrossfireServerClass> serverClass = NULL; HRESULT hr = CoGetClassObject(CLSID_CrossfireServer, CLSCTX_ALL, 0, IID_ICrossfireServerClass, (LPVOID*)&serverClass); if (FAILED(hr)) { Logger::error("IECrossfireBHO.initServer(): CoGetClassObject() failed", hr); return false; } hr = serverClass->GetServer(/*applicationHwnd,*/ &m_server); if (FAILED(hr)) { Logger::error("IECrossfireBHO.initServer(): GetController() failed", hr); return false; } hr = m_server->getState(&m_serverState); if (FAILED(hr)) { Logger::error("IECrossfireBHO.initServer(): getState() failed", hr); } if (m_serverState == STATE_CONNECTED) { hr = m_server->registerBrowser(GetCurrentProcessId(), this); if (FAILED(hr)) { Logger::error("IECrossfireBHO.initServer(): registerBrowser() failed", hr); /* continue */ } } return true; }
HOOKFUNC HRESULT STDAPICALLTYPE MyCoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, LPVOID pvReserved, REFIID riid, LPVOID FAR* ppv) { const char* oldName = tls.curThreadCreateName; PreCoGetClassObject(rclsid,riid,ppv, __FUNCTION__, oldName); HRESULT rv = CoGetClassObject(rclsid, dwClsContext, pvReserved, riid, ppv); PostCoGetClassObject(rclsid,riid,ppv, rv, oldName); return rv; }
HRESULT CoCreateInstanceEx( REFCLSID rclsid, const IUnknown *punkOuter, CLSCTX ctx, COMSERVERINFO *serverInfo, uint32 count, MULTI_QI *multi_QI ) { HRESULT hr; IClassFactory *pcf; IUnknown *punk; uint32 i, successfulQueries; hr = CoGetClassObject( rclsid, ctx, serverInfo, IID_IClassFactory, (void **)&pcf ); if( SUCCEEDED( hr ) ) { hr = pcf -> lpVtbl -> CreateInstance( pcf, punkOuter, IID_IUnknown, (void **)&punk ); if( SUCCEEDED( hr ) ) { for( i = 0; i < count; i++ ) { multi_QI[i].hr = punk -> lpVtbl -> QueryInterface( punk, multi_QI[i].riid, &multi_QI[i].pvObj ); if( SUCCEEDED( multi_QI[i].hr ) ) successfulQueries++; } punk -> lpVtbl -> Release( punk ); if( successfulQueries == 0 ) hr = E_NOINTERFACE; else if( successfulQueries < count ) hr = S_NOTALLINTERFACES; else if( successfulQueries == count ) hr = S_OK; } } return hr; }
CrossfireServer::~CrossfireServer() { delete m_bpManager; std::map<DWORD,CrossfireContext*>::iterator iterator = m_contexts->begin(); while (iterator != m_contexts->end()) { delete iterator->second; iterator++; } delete m_contexts; std::map<DWORD, IBrowserContext*>::iterator iterator2 = m_browsers->begin(); while (iterator2 != m_browsers->end()) { iterator2->second->Release(); iterator2++; } delete m_browsers; std::vector<CrossfireEvent*>::iterator iterator3 = m_pendingEvents->begin(); while (iterator3 != m_pendingEvents->end()) { if (m_connection) { sendEvent(*iterator3); } delete *iterator3; iterator3++; } delete m_pendingEvents; delete m_inProgressPacket; delete m_processor; if (m_connection) { delete m_connection; } if (m_messageWindow) { DestroyWindow(m_messageWindow); UnregisterClass(WindowClass, GetModuleHandle(NULL)); } // if (m_windowHandle) { CComPtr<ICrossfireServerClass> serverClass = NULL; HRESULT hr = CoGetClassObject(CLSID_CrossfireServer, CLSCTX_ALL, 0, IID_ICrossfireServerClass, (LPVOID*)&serverClass); if (FAILED(hr)) { Logger::error("~CrossfireServer: CoGetClassObject() failed", hr); return; } hr = serverClass->RemoveServer(/*m_windowHandle*/ 0); if (FAILED(hr)) { Logger::error("~CrossfireServer: RemoveServer() failed", hr); return; } // } }
int main(int argc, char **argv) { IExample *exampleObj; IClassFactory *classFactory; HRESULT hr; // We must initialize OLE before we do anything with COM objects. NOTE: // some COM components, such as the IE browser engine, require that you // use OleInitialize() instead. But our COM component doesn't require this if (!CoInitialize(0)) { // Get IExample.DLL's IClassFactory if ((hr = CoGetClassObject(&CLSID_IExample, CLSCTX_INPROC_SERVER, 0, &IID_IClassFactory, &classFactory))) MessageBox(0, "Can't get IClassFactory", "CoGetClassObject error", MB_OK|MB_ICONEXCLAMATION); else { // Create an IExample object if ((hr = classFactory->lpVtbl->CreateInstance(classFactory, 0, &IID_IExample, &exampleObj))) { classFactory->lpVtbl->Release(classFactory); MessageBox(0, "Can't create IExample object", "CreateInstance error", MB_OK|MB_ICONEXCLAMATION); } else { char buffer[80]; // Release the IClassFactory. We don't need it now that we have the one // IExample we want classFactory->lpVtbl->Release(classFactory); // Call SetString to set the text "Hello world!" exampleObj->lpVtbl->SetString(exampleObj, "Hello world!"); // Retrieve the string to make sure we get "Hello world!" exampleObj->lpVtbl->GetString(exampleObj, buffer, sizeof(buffer)); printf("string = %s (should be Hello World!)\n", buffer); // Release the IExample now that we're done with it exampleObj->lpVtbl->Release(exampleObj); } } // When finally done with OLE, free it CoUninitialize(); } else MessageBox(0, "Can't initialize COM", "CoInitialize error", MB_OK|MB_ICONEXCLAMATION); return(0); }
static void test_OleCreateFontIndirect(void) { FONTDESC fontdesc; IUnknown *unk, *unk2; IFont *font; HRESULT hr; fontdesc.cbSizeofstruct = sizeof(fontdesc); fontdesc.lpstrName = arial_font; fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */ fontdesc.sWeight = FW_NORMAL; fontdesc.sCharset = ANSI_CHARSET; fontdesc.fItalic = FALSE; fontdesc.fUnderline = FALSE; fontdesc.fStrikethrough = FALSE; hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font); EXPECT_HR(hr, S_OK); IFont_Release(font); /* play with cbSizeofstruct value */ fontdesc.cbSizeofstruct = sizeof(fontdesc)-1; hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font); EXPECT_HR(hr, S_OK); IFont_Release(font); fontdesc.cbSizeofstruct = sizeof(fontdesc)+1; hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font); EXPECT_HR(hr, S_OK); IFont_Release(font); fontdesc.cbSizeofstruct = 0; hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void**)&font); EXPECT_HR(hr, S_OK); IFont_Release(font); hr = OleInitialize(NULL); ok(hr == S_OK, "got 0x%08x\n", hr); hr = CoGetClassObject(&CLSID_StdFont, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&unk); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void**)&unk2); ok(hr == S_OK, "got 0x%08x\n", hr); IUnknown_Release(unk); IUnknown_Release(unk2); OleUninitialize(); }
void CPageConnect::CreateSessionThreadProc() { // Create the AdminSession class object IAdminSessionClassPtr spClass; HRESULT hr = CoGetClassObject(__uuidof(AdminSession), CLSCTX_LOCAL_SERVER, NULL, __uuidof(spClass), (void**)&spClass); if (FAILED(hr)) { PostMessage(wm_SessionFailed, hr); return; } // Create an instance of the host object for an IAdminSessionHost interface AdminSessionSecureHost xHost; // Create an AdminSession object IAdminSessionPtr spSession; hr = spClass->CreateSession(&xHost, &spSession); ::CoDisconnectObject(&xHost, 0); if (FAILED(hr)) { PostMessage(wm_SessionFailed, hr); return; } // Get a reference to the GIT IGlobalInterfaceTablePtr spGIT; hr = spGIT.CreateInstance(CLSID_StdGlobalInterfaceTable); if (FAILED(hr)) { PostMessage(wm_SessionFailed, hr); return; } // Add the Session pointer to the GIT DWORD dwCookie = 0; hr = spGIT->RegisterInterfaceInGlobal(spSession, __uuidof(IAdminSession), &dwCookie); if (FAILED(hr)) { PostMessage(wm_SessionFailed, hr); return; } TCHandle shEvent = CreateEvent(NULL, false, false, NULL); PostMessage(wm_SessionSucceeded, dwCookie, (LPARAM)shEvent.GetHandle()); WaitForSingleObject(shEvent, INFINITE); }
static HRESULT get_protocol_cf(LPCWSTR schema, DWORD schema_len, CLSID *pclsid, IClassFactory **ret) { WCHAR str_clsid[64]; HKEY hkey = NULL; DWORD res, type, size; CLSID clsid; LPWSTR wszKey; HRESULT hres; static const WCHAR wszProtocolsKey[] = {'P','R','O','T','O','C','O','L','S','\\','H','a','n','d','l','e','r','\\'}; static const WCHAR wszCLSID[] = {'C','L','S','I','D',0}; wszKey = heap_alloc(sizeof(wszProtocolsKey)+(schema_len+1)*sizeof(WCHAR)); memcpy(wszKey, wszProtocolsKey, sizeof(wszProtocolsKey)); memcpy(wszKey + sizeof(wszProtocolsKey)/sizeof(WCHAR), schema, (schema_len+1)*sizeof(WCHAR)); res = RegOpenKeyW(HKEY_CLASSES_ROOT, wszKey, &hkey); heap_free(wszKey); if(res != ERROR_SUCCESS) { TRACE("Could not open protocol handler key\n"); return MK_E_SYNTAX; } size = sizeof(str_clsid); res = RegQueryValueExW(hkey, wszCLSID, NULL, &type, (LPBYTE)str_clsid, &size); RegCloseKey(hkey); if(res != ERROR_SUCCESS || type != REG_SZ) { WARN("Could not get protocol CLSID res=%d\n", res); return MK_E_SYNTAX; } hres = CLSIDFromString(str_clsid, &clsid); if(FAILED(hres)) { WARN("CLSIDFromString failed: %08x\n", hres); return hres; } if(pclsid) *pclsid = clsid; if(!ret) return S_OK; hres = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)ret); return SUCCEEDED(hres) ? S_OK : MK_E_SYNTAX; }
extern "C" HRESULT CoCreateInstance(REFCLSID requestedClassID, LPUNKNOWN outerAggregateIUnknown, DWORD /*dwClsContext*/, REFIID objectInterfaceID, LPVOID* objectInterface) { *objectInterface = NULL; IClassFactory* pIFactory = NULL; HRESULT hr = CoGetClassObject(requestedClassID, static_cast<unsigned long>(CLSCTX_INPROC), (void *)0, IID_IClassFactory, (void **)&pIFactory); if (SUCCEEDED(hr)) { // Create the component hr = pIFactory->CreateInstance(outerAggregateIUnknown, objectInterfaceID, objectInterface); // Release the class factory pIFactory->Release(); } return hr; }
HRESULT IXArrayDB::CreateInstanceLic( REFCLSID clsid, LPUNKNOWN pUnkOuter, DWORD dwClsCtx, REFIID iid, LPVOID* ppv ) { HRESULT hr; LPCLASSFACTORY2 pClassFactory = NULL; BSTR bstrLKey = ::SysAllocStringLen( LKey, zsizeof(LKey)/sizeof(WCHAR)); if (SUCCEEDED(hr = CoGetClassObject(clsid, dwClsCtx, NULL, IID_IClassFactory2, (void**)&pClassFactory))) { ASSERT(pClassFactory != NULL); hr = pClassFactory->CreateInstanceLic( pUnkOuter, NULL, iid, bstrLKey , ppv); pClassFactory->Release(); } ::SysFreeString( bstrLKey ); return hr; }
HRESULT CoCreateInstance( REFCLSID rclsid, const IUnknown *punkOuter, CLSCTX ctx, REFIID riid, void **ppv ) { HRESULT hr; IClassFactory *pcf; hr = CoGetClassObject( rclsid, ctx, NULL, IID_IClassFactory, (void **)&pcf ); if( SUCCEEDED( hr ) ) { hr = pcf -> lpVtbl -> CreateInstance( pcf, punkOuter, riid, ppv ); pcf -> lpVtbl -> Release( pcf ); } return hr; }
static void test_mk_protocol(void) { IClassFactory *cf; HRESULT hres; test_protocol = MK_PROTOCOL; hres = CoGetClassObject(&CLSID_MkProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&cf); ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres); if(FAILED(hres)) return; cache_file = cache_file1; test_protocol_url(cf, blank_url3, TRUE); cache_file = cache_file2; test_protocol_url(cf, blank_url7, TRUE); cache_file = cache_file3; test_protocol_url(cf, blank_url8, FALSE); IClassFactory_Release(cf); }
BOOL CDBDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: add reinitialization code here // (SDI documents will reuse this document) // create a database object through the exported function & class factory object IClassFactory *pDBFactory=NULL; HRESULT hRes; hRes=CoGetClassObject(CLSID_DBSAMPLE, CLSCTX_SERVER, NULL, IID_IClassFactory, (void**) &pDBFactory); if (FAILED(hRes)) { CString csError; csError.Format(_T("Error %x obtaining class factory for DB Object!"), hRes); AfxMessageBox(csError); return FALSE; } hRes=pDBFactory->CreateInstance(NULL, IID_IDB, (void**) &m_pDB); if (FAILED(hRes)) { CString csError; csError.Format(_T("Error %x creating DB Object!"), hRes); AfxMessageBox(csError); return FALSE; } pDBFactory->Release(); // do not need the factory anymore // equivalent way of creating object: // hRes=CoCreateInstance(CLSID_DBSAMPLE, NULL, CLSCTX_SERVER, IID_IDB, (void**) &pDBFactory); // initialize state of the document: m_csData="No data yet!"; // string displayed in views: last data read m_nCount=0; // number of writes done through this document m_nTable=-1; // number of last table created through this document return TRUE; }
void CSH_XAudio2::InitializeXAudio2() { HRESULT result = S_OK; result = CoInitializeEx(0, COINIT_MULTITHREADED); assert(SUCCEEDED(result)); //Instantiate XAudio2's class factory to prevent DLL from being unloaded by COM //Otherwise, DllCanUnloadNow always returns S_OK (can be unloaded) result = CoGetClassObject(__uuidof(XAudio2), CLSCTX_INPROC_SERVER, NULL, __uuidof(IClassFactory), reinterpret_cast<void**>(&m_classFactory)); assert(SUCCEEDED(result)); result = XAudio2Create(&m_xaudio2); assert(SUCCEEDED(result)); result = m_xaudio2->CreateMasteringVoice(&m_masteringVoice); assert(SUCCEEDED(result)); m_voiceCallback = new VoiceCallback(this); { WAVEFORMATEX waveFormat = {}; memset(&waveFormat, 0, sizeof(WAVEFORMATEX)); waveFormat.nSamplesPerSec = SAMPLE_RATE; waveFormat.wBitsPerSample = 16; waveFormat.nChannels = 2; waveFormat.cbSize = 0; waveFormat.wFormatTag = WAVE_FORMAT_PCM; waveFormat.nBlockAlign = (waveFormat.wBitsPerSample / 8) * waveFormat.nChannels; waveFormat.nAvgBytesPerSec = waveFormat.nBlockAlign * waveFormat.nSamplesPerSec; result = m_xaudio2->CreateSourceVoice(&m_sourceVoice, &waveFormat, 0, 2.0f, m_voiceCallback); assert(SUCCEEDED(result)); } result = m_sourceVoice->Start(); assert(SUCCEEDED(result)); }
void QAxWidgetTaskMenu::setActiveXControl() { QAxSelect *dialog = new QAxSelect(m_axwidget->topLevelWidget()); if (dialog->exec()) { QUuid clsid = dialog->clsid(); QString key; IClassFactory2 *cf2 = 0; CoGetClassObject(clsid, CLSCTX_SERVER, 0, IID_IClassFactory2, (void**)&cf2); if (cf2) { BSTR bKey; HRESULT hres = cf2->RequestLicKey(0, &bKey); if (hres == CLASS_E_NOTLICENSED) { QMessageBox::warning(m_axwidget->topLevelWidget(), tr("Licensed Control"), tr("The control requires a design-time license")); clsid = QUuid(); } else { key = QString::fromWCharArray(bKey); } cf2->Release(); } if (!clsid.isNull()) { QDesignerFormWindowInterface *formWin = QDesignerFormWindowInterface::findFormWindow(m_axwidget); Q_ASSERT(formWin != 0); QString value = clsid.toString(); if (!key.isEmpty()) { value += QLatin1Char(':'); value += key; } formWin->commandHistory()->push(new SetControlCommand(m_axwidget, formWin, value)); } } delete dialog; }
HRESULT dhCreateObjectEx(LPCOLESTR szProgId, REFIID riid, DWORD dwClsContext, COSERVERINFO * pServerInfo, void ** ppv) { CLSID clsid; HRESULT hr; IClassFactory * pCf = NULL; DH_ENTER(L"CreateObjectEx"); if (!szProgId || !riid || !ppv) return DH_EXIT(E_INVALIDARG, szProgId); if (L'{' == szProgId[0]) hr = CLSIDFromString((LPOLESTR) szProgId, &clsid); else hr = CLSIDFromProgID(szProgId, &clsid); if (SUCCEEDED(hr)) hr = CoGetClassObject(&clsid, dwClsContext, pServerInfo, &IID_IClassFactory, (void **) &pCf); if (SUCCEEDED(hr)) hr = pCf->lpVtbl->CreateInstance(pCf, NULL, riid, ppv); if (pCf) pCf->lpVtbl->Release(pCf); return DH_EXIT(hr, szProgId); }
int main() { ::CoInitialize(NULL); IClassFactory *pDBFactory=NULL; IDB *pDB; HRESULT hRes; hRes=CoGetClassObject(CLSID_DBSAMPLE, CLSCTX_SERVER, NULL, IID_IClassFactory, (void**) &pDBFactory); if (FAILED(hRes)) { TString csError; csError.format(_T("Error %d creating DB Object : %d"), hRes, GetLastError()); //AfxMessageBox(csError); //return FALSE; printf("%s\n", csError.c_str()); //return FALSE; } hRes=pDBFactory->CreateInstance(NULL, IID_IDB, (void**) &pDB); if (FAILED(hRes)) { TString csError; csError.format(_T("Error %d creating DB Object : %d"), hRes, GetLastError()); //AfxMessageBox(csError); //return FALSE; printf("%s\n", csError.c_str()); //return FALSE; } pDB->Read(0, 0, ""); //pDB->Release(); //pDBFactory->Release(); // Do not need th ::CoUninitialize(); return 0; }
int main(int argc, char **argv) { IExample3 *exampleObj; IClassFactory *classFactory; HRESULT hr; // We must initialize OLE before we do anything with COM objects. NOTE: // some COM components, such as the IE browser engine, require that you // use OleInitialize() instead. But our COM component doesn't require this if (!CoInitialize(0)) { // Get IExample3.DLL's IClassFactory if ((hr = CoGetClassObject(&CLSID_IExample3, CLSCTX_INPROC_SERVER, 0, &IID_IClassFactory, &classFactory))) MessageBox(0, "Can't get IClassFactory", "CoGetClassObject error", MB_OK|MB_ICONEXCLAMATION); else { // Create an IExample object if ((hr = classFactory->lpVtbl->CreateInstance(classFactory, 0, &IID_IExample3, &exampleObj))) { classFactory->lpVtbl->Release(classFactory); MessageBox(0, "Can't create IExample3 object", "CreateInstance error", MB_OK|MB_ICONEXCLAMATION); } else { // Release the IClassFactory. We don't need it now that we have the one // IExample3 we want classFactory->lpVtbl->Release(classFactory); //========================================================================== // STUDY THIS //========================================================================== { // Get the IDispatch object for the Ports collection, and stuff it into our variable "portsObj". // NOTE: What our DLL is really returning is a MyRealICollection object. But this app doesn't // know that. All we know here is that this object is an IDispatch. So its VTable has the 3 // IUnknown functions (QueryInterface, AddRef, and Release) and the 4 IDispatch functions // (GetTypeInfoCount, GetTypeInfo, GetIDsOfNames, and Invoke). And that's all as far as we're // concerned. If the object has any other functions, we can't call them directly by referencing // lpVtbl. We have to call those extra functions indirectly via the Invoke function, as we'll // see below IDispatch *portsObj; if ((hr = exampleObj->lpVtbl->GetPorts(exampleObj, &portsObj))) MessageBox(0, "Can't get the Ports collection (IDispatch) object", "GetPorts error", MB_OK|MB_ICONEXCLAMATION); else { VARIANT ret; ULONG count, i; DISPID dispid; OLECHAR *funcName; funcName = (OLECHAR *)L"Count"; // In order to call our collection's Count function, we have to do it indirectly by calling our // collection's Invoke function. This is a pain in the ass. Thank you, Microsoft's Visual Basic // team. First, we need to discover the DISPID (number) associated with the Count function. We // do this by calling the collection's GetIDsOfNames function. We pass it a handle to a // unicode string of the function name we want (ie, L"Count"). We also pass it a pointer to some // variable where it returns the DISPID if ((hr = portsObj->lpVtbl->GetIDsOfNames(portsObj, &IID_NULL, &funcName, 1, LOCALE_USER_DEFAULT, &dispid))) MessageBox(0, "Can't get Count()'s DISPID", "GetIDsOfNames error", MB_OK|MB_ICONEXCLAMATION); else { // Ok, now we have the DISPID for the Count function. It's stored in our variable "dispid". // // We can now call Invoke to indirectly call Count. This is going to be more of a pain in // the ass because we have to initialize and pass a Visual Basic DISPPARAMS struct. And // if the Count function is passed any args, we need to set this DISPPARMS rgvarg member to // point to an array of VARIANT structs -- one per each arg we need to pass to Count. // Fortunately, the Count function is passed no args, so we can simply zero out the DISPPARAMS DISPPARAMS dspp; ZeroMemory(&dspp, sizeof(DISPPARAMS)); // Now we can actually call Invoke. We pass the DISPID for the Count function. This // causes Invoke to call Count. We also pass a VARIANT where we want Count to return // whatever our IDL file marks as its [out, retval]. In this case, the VARIANT is // going to store a long value which is a count of how many items are in the collection. // Because the Count function is marked as [propget] in our IDL, we need to indicate // this by specifying the DISPATCH_PROPERTYGET flag. Oh, and we need to initialize the // VARIANT first, by calling VariantInit VariantInit(&ret); if ((hr = portsObj->lpVtbl->Invoke(portsObj, dispid, &IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dspp, &ret, 0, 0))) MessageBox(0, "Can't get a count of items", "Invoke/Count error", MB_OK|MB_ICONEXCLAMATION); else { VARIANT args[1]; // Pull the count out of the return VARIANT. To be perfectly safe, we really should // check the VARIANT's vt member to make sure it's VT_I4 (ie, a long was stuffed into // it). After all, theoretically we could have been returned a VT_BSTR of L"100" (if // there were 100 items). Then, we'd have use atoi on the VARIANT's bstrVal member. // And after that, we'd have to SysFreeString our VARIANT's bstrVal. But, we're going // to assume that the Count function didn't do something totally stupid (even though // MS Visual Basic programmers thought this whole thing up, and if one of them had // written our COM DLL... well...) count = ret.lVal; // If the Count function returned a VT_BSTR in our VARIANT, we'd have to SysFreeString // our VARIANT's bstrVal. If the Count function returned a VT_UNKNOWN or VT_DISPATCH, // we'd have to Release() on the VARIANT's punkVal. A call to VariantClear() does this // for us. It also resets the VARIANT's vt member to VT_EMPTY so we can reuse it on // the following call to Invoke (when we indirectly call the Item function) VariantClear(&ret); // Now let's do a loop, calling Item (indirectly via Invoke) to fetch (and display) // each port name. Normally, we'd have to first call GetIDsOfNames again, this time // passing the string L"Item" to get the DISPID for the Item function. But we know // that it must have a DISPID of DISPID_VALUE. So we can simply pass DISPID_VALUE to // Invoke in order to indirectly call Item(). // // For passing any args to Item, we need a DISPPARAMS. We'll just reuse the same // DISPPARAMS we used above. // // And we do have to pass 1 arg to Item (a long indicating which item we want // fetched), so we need to fill in the array of 1 VARIANT struct. First we set the // DISPPARMS cArgs member to 1 to indicate we're passing only one arg. Now // we need to set its rgvarg member to point to a VARIANT. And finally, we need // to fill in this VARIANT's lVal with the item number we wish to fetch, and set // the vt member to VT_I4 (because we're stuffing a long value into the VARIANT). VariantInit(&args[0]); ZeroMemory(&dspp, sizeof(DISPPARAMS)); dspp.cArgs = 1; dspp.rgvarg = &args[0]; args[0].vt = VT_I4; for (i = 0; i < count; i++) { // Indicate (to the Item function) which item's port name we want args[0].lVal = i; // Call Invoke to indirectly call Item. We pass a DISPID of DISPID_VALUE. This // causes Invoke to call Item. We also pass a VARIANT where we want Item to return // the value of the item we requested. In this case, the VARIANT is going to return // a BSTR of that item's port name. Because the Item function is marked as [propget] // in our IDL, we need to indicate this by specifying the DISPATCH_PROPERTYGET flag if ((hr = portsObj->lpVtbl->Invoke(portsObj, DISPID_VALUE, &IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dspp, &ret, 0, 0))) { MessageBox(0, "Can't get next item's port name", "Invoke/Item error", MB_OK|MB_ICONEXCLAMATION); break; } else { // Display the port name. NOTE: It's a unicode string printf("%S\n", ret.bstrVal); // Call to VariantClear() to SysFreeString that BSTR, and also reset the // VARIANT's vt member to VT_EMPTY so we can reuse it on the next call // to Invoke (when we indirectly call the Item function again) VariantClear(&ret); } } } } // Release the Ports collection IDispatch now that we're done with it portsObj->lpVtbl->Release(portsObj); } } //========================================================================== // Release the IExample3 now that we're done with it exampleObj->lpVtbl->Release(exampleObj); } } // When finally done with OLE, free it CoUninitialize(); } else MessageBox(0, "Can't initialize COM", "CoInitialize error", MB_OK|MB_ICONEXCLAMATION); return(0); }
void Application_InternetExplorer::visitGroup(VisitEvent* visitEvent) { DWORD *error = NULL; int n_visited_urls = 0; int to_visit = 0; int n_visiting = 0; int n_urls = visitEvent->getUrls().size(); IClassFactory* internet_explorer_factory; // Get a link to the IE factory for creating IE instances HRESULT hr = CoGetClassObject(CLSID_InternetExplorer, CLSCTX_LOCAL_SERVER, NULL, IID_IClassFactory, (void**)&internet_explorer_factory); // Allocate on the heap so threads can use the information InternetExplorerInstance** iexplore_instances = (InternetExplorerInstance**)malloc(sizeof(InternetExplorerInstance*)*n_urls); for(int i = 0; i < n_urls; i++) { iexplore_instances[i] = new InternetExplorerInstance(internet_explorer_factory); } VISIT_INFO* visit_information = new VISIT_INFO[n_urls]; // Loop until all urls have been visited while(n_visited_urls < n_urls) { for(int i = 0; i < MAX_WORKER_THREADS; i++) { if(!worker_thread_busy[i] && n_visiting < n_urls) { // Give the threads something to do visit_information[to_visit].internet_explorer_instance = iexplore_instances[to_visit]; visit_information[to_visit].url = visitEvent->getUrls().at(to_visit); worker_thread_data[i] = (LPVOID*)&visit_information[to_visit++]; worker_thread_busy[i] = true; n_visiting++; SetEvent(worker_has_data[i]); } } // Wait for one of the workers threads to finish DWORD dwWait = WaitForMultipleObjects(MAX_WORKER_THREADS, worker_finished, false, 60*1000); OutputDebugStringA("IE Visit Group Worker Threads Finished.\n"); // If one has finished then a url has been visited int index = dwWait - WAIT_OBJECT_0; if(index < MAX_WORKER_THREADS && !worker_thread_busy[index]) { n_visited_urls++; } } // Give the visit event a success or error code based on the visitaion of each url for(int i = 0; i < n_urls; i++) { Url* url = visitEvent->getUrls().at(i); visitEvent->setErrorCode(url->getMajorErrorCode()); } OutputDebugStringA("IE Visit Group set errors on urls.\n"); DWORD errorCode = closeAllInternetExplorers(internet_explorer_factory); if(errorCode!=0) { visitEvent->setErrorCode( CAPTURE_VISITATION_WARNING ); } OutputDebugStringA("IE Visit Group closed all instances.\n"); //Delete all IE instance objects delete [] visit_information; for(int i = 0; i < n_urls; i++) { delete iexplore_instances[i]; } free(iexplore_instances); OutputDebugStringA("IE Visit Group delete IE instances\n"); // Free the COM interface stuff ULONG num_references = internet_explorer_factory->Release(); }
static void test_its_protocol(void) { IInternetProtocolInfo *info; IClassFactory *factory; IUnknown *unk; ULONG ref; HRESULT hres; static const WCHAR wrong_url1[] = {'i','t','s',':','t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','.','h','t','m','l',0}; static const WCHAR wrong_url2[] = {'i','t','s',':','t','e','s','.','c','h','m',':',':','b','/','l','a','n','k','.','h','t','m','l',0}; static const WCHAR wrong_url3[] = {'i','t','s',':','t','e','s','t','.','c','h','m','/','b','l','a','n','k','.','h','t','m','l',0}; static const WCHAR wrong_url4[] = {'m','k',':','@','M','S','I','T','S','t','o','r',':', 't','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0}; static const WCHAR wrong_url5[] = {'f','i','l','e',':', 't','e','s','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0}; test_protocol = ITS_PROTOCOL; hres = CoGetClassObject(&CLSID_ITSProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk); ok(hres == S_OK || broken(hres == REGDB_E_CLASSNOTREG), /* Some W95 and NT4 */ "CoGetClassObject failed: %08x\n", hres); if(FAILED(hres)) return; hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&info); ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo: %08x\n", hres); hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory); ok(hres == S_OK, "Could not get IClassFactory interface\n"); if(SUCCEEDED(hres)) { IInternetProtocol *protocol; hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol); ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres); if(SUCCEEDED(hres)) { test_its_protocol_info(protocol); test_protocol_fail(protocol, wrong_url1, STG_E_FILENOTFOUND); test_protocol_fail(protocol, wrong_url2, STG_E_FILENOTFOUND); test_protocol_fail(protocol, wrong_url3, STG_E_FILENOTFOUND); hres = IInternetProtocol_Start(protocol, wrong_url4, &protocol_sink, &bind_info, 0, 0); ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "Start failed: %08x, expected INET_E_USE_DEFAULT_PROTOCOLHANDLER\n", hres); hres = IInternetProtocol_Start(protocol, wrong_url5, &protocol_sink, &bind_info, 0, 0); ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "Start failed: %08x, expected INET_E_USE_DEFAULT_PROTOCOLHANDLER\n", hres); ref = IInternetProtocol_Release(protocol); ok(!ref, "protocol ref=%d\n", ref); test_protocol_url(factory, blank_url1, TRUE); test_protocol_url(factory, blank_url2, TRUE); test_protocol_url(factory, blank_url3, TRUE); test_protocol_url(factory, blank_url4, TRUE); test_protocol_url(factory, blank_url5, TRUE); test_protocol_url(factory, blank_url6, TRUE); test_protocol_url(factory, blank_url8, TRUE); bindf = BINDF_FROMURLMON | BINDF_NEEDFILE; test_protocol_url(factory, blank_url1, TRUE); } IClassFactory_Release(factory); } IUnknown_Release(unk); }
static void test_about_protocol(void) { IInternetProtocolInfo *protocol_info; IUnknown *unk; IClassFactory *factory; HRESULT hres; hres = CoGetClassObject(&CLSID_AboutProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk); ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres); if(FAILED(hres)) return; hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info); ok(hres == S_OK, "Could not get IInternetProtocolInfo interface: %08x\n", hres); if(SUCCEEDED(hres)) { WCHAR buf[128]; DWORD size; int i; for(i = PARSE_CANONICALIZE; i <= PARSE_UNESCAPE; i++) { if(i != PARSE_SECURITY_URL && i != PARSE_DOMAIN) { hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_blank_url, i, 0, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == INET_E_DEFAULT_ACTION, "[%d] failed: %08x, expected INET_E_DEFAULT_ACTION\n", i, hres); } } hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_blank_url, PARSE_SECURITY_URL, 0, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == S_OK, "ParseUrl failed: %08x\n", hres); ok(!lstrcmpW(about_blank_url, buf), "buf != blank_url\n"); size = 0xdeadbeef; hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_blank_url, PARSE_SECURITY_URL, 0, buf, 3, &size, 0); ok(hres == S_FALSE, "ParseUrl failed: %08x, expected S_FALSE\n", hres); ok(size == 12, "size = %d\n", size); hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_test_url, PARSE_SECURITY_URL, 0, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == S_OK, "ParseUrl failed: %08x\n", hres); ok(!lstrcmpW(about_test_url, buf), "buf != test_url\n"); ok(size == 11, "size = %d\n", size); size = 0xdeadbeef; buf[0] = '?'; hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_blank_url, PARSE_DOMAIN, 0, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == S_OK || hres == E_FAIL, "ParseUrl failed: %08x\n", hres); ok(buf[0] == '?', "buf changed\n"); ok(size == sizeof(about_blank_url)/sizeof(WCHAR) || size == sizeof(buf)/sizeof(buf[0]), /* IE8 */ "size=%d\n", size); if (0) { /* Crashes on windows */ size = 0xdeadbeef; buf[0] = '?'; hres = IInternetProtocolInfo_ParseUrl(protocol_info, NULL, PARSE_DOMAIN, 0, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == E_FAIL, "ParseUrl failed: %08x\n", hres); ok(buf[0] == '?', "buf changed\n"); ok(size == 1, "size=%u, expected 1\n", size); buf[0] = '?'; hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_blank_url, PARSE_DOMAIN, 0, buf, sizeof(buf)/sizeof(buf[0]), NULL, 0); ok(hres == E_POINTER, "ParseUrl failed: %08x\n", hres); ok(buf[0] == '?', "buf changed\n"); buf[0] = '?'; hres = IInternetProtocolInfo_ParseUrl(protocol_info, NULL, PARSE_DOMAIN, 0, buf, sizeof(buf)/sizeof(buf[0]), NULL, 0); ok(hres == E_POINTER, "ParseUrl failed: %08x\n", hres); ok(buf[0] == '?', "buf changed\n"); } hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_blank_url, PARSE_UNESCAPE+1, 0, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == INET_E_DEFAULT_ACTION, "ParseUrl failed: %08x, expected INET_E_DEFAULT_ACTION\n", hres); size = 0xdeadbeef; hres = IInternetProtocolInfo_CombineUrl(protocol_info, about_blank_url, about_test_url, 0, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "CombineUrl failed: %08x\n", hres); ok(size == 0xdeadbeef, "size=%d\n", size); size = 0xdeadbeef; hres = IInternetProtocolInfo_CombineUrl(protocol_info, about_blank_url, about_test_url, URL_FILE_USE_PATHURL, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "CombineUrl failed: %08x\n", hres); ok(size == 0xdeadbeef, "size=%d\n", size); size = 0xdeadbeef; hres = IInternetProtocolInfo_CombineUrl(protocol_info, NULL, NULL, URL_FILE_USE_PATHURL, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "CombineUrl failed: %08x\n", hres); ok(size == 0xdeadbeef, "size=%d\n", size); hres = IInternetProtocolInfo_CompareUrl(protocol_info, about_blank_url, about_blank_url, 0); ok(hres == E_NOTIMPL, "CompareUrl failed: %08x\n", hres); hres = IInternetProtocolInfo_CompareUrl(protocol_info, NULL, NULL, 0xdeadbeef); ok(hres == E_NOTIMPL, "CompareUrl failed: %08x\n", hres); for(i=0; i<30; i++) { switch(i) { case QUERY_CAN_NAVIGATE: case QUERY_USES_NETWORK: case QUERY_IS_CACHED: case QUERY_IS_INSTALLEDENTRY: case QUERY_IS_CACHED_OR_MAPPED: case QUERY_IS_SECURE: case QUERY_IS_SAFE: case QUERY_USES_HISTORYFOLDER: case QUERY_IS_CACHED_AND_USABLE_OFFLINE: break; default: hres = IInternetProtocolInfo_QueryInfo(protocol_info, about_blank_url, i, 0, buf, sizeof(buf), &size, 0); ok(hres == E_FAIL, "QueryInfo(%d) returned: %08x, expected E_FAIL\n", i, hres); } } hres = IInternetProtocolInfo_QueryInfo(protocol_info, about_blank_url, QUERY_CAN_NAVIGATE, 0, buf, sizeof(buf), &size, 0); ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER || hres == E_FAIL, /* win2k */ "QueryInfo returned: %08x, expected INET_E_USE_DEFAULT_PROTOCOLHANDLER or E_FAIL\n", hres); size = 0xdeadbeef; memset(buf, '?', sizeof(buf)); hres = IInternetProtocolInfo_QueryInfo(protocol_info, about_blank_url, QUERY_USES_NETWORK, 0, buf, sizeof(buf), &size, 0); ok(hres == S_OK, "QueryInfo(QUERY_USES_NETWORK) failed: %08x\n", hres); ok(size == sizeof(DWORD), "size=%d\n", size); ok(!*(DWORD*)buf, "buf=%d\n", *(DWORD*)buf); memset(buf, '?', sizeof(buf)); hres = IInternetProtocolInfo_QueryInfo(protocol_info, about_blank_url, QUERY_USES_NETWORK, 0, buf, sizeof(buf), NULL, 0); ok(hres == S_OK, "QueryInfo(QUERY_USES_NETWORK) failed: %08x\n", hres); ok(!*(DWORD*)buf, "buf=%d\n", *(DWORD*)buf); hres = IInternetProtocolInfo_QueryInfo(protocol_info, about_blank_url, QUERY_USES_NETWORK, 0, buf, 3, &size, 0); ok(hres == E_FAIL, "QueryInfo(QUERY_USES_NETWORK) failed: %08x, expected E_FAIL\n", hres); hres = IInternetProtocolInfo_QueryInfo(protocol_info, about_blank_url, QUERY_USES_NETWORK, 0, NULL, sizeof(buf), &size, 0); ok(hres == E_FAIL, "QueryInfo(QUERY_USES_NETWORK) failed: %08x, expected E_FAIL\n", hres); hres = IInternetProtocolInfo_QueryInfo(protocol_info, about_blank_url, 60, 0, NULL, sizeof(buf), &size, 0); ok(hres == E_FAIL, "QueryInfo failed: %08x, expected E_FAIL\n", hres); IInternetProtocolInfo_Release(protocol_info); } hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory); ok(hres == S_OK, "Could not get IClassFactory interface\n"); if(SUCCEEDED(hres)) { do_test_about_protocol(factory, 0); do_test_about_protocol(factory, BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NEEDFILE); IClassFactory_Release(factory); } IUnknown_Release(unk); }
static void test_javascript_protocol(void) { IInternetProtocolInfo *protocol_info; IUnknown *unk; IClassFactory *factory; HRESULT hres; hres = CoGetClassObject(&CLSID_JSProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk); ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres); if(FAILED(hres)) return; hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info); ok(hres == S_OK, "Could not get IInternetProtocolInfo interface: %08x\n", hres); if(SUCCEEDED(hres)) { WCHAR buf[128]; DWORD size; int i; for(i = PARSE_CANONICALIZE; i <= PARSE_UNESCAPE; i++) { if(i != PARSE_SECURITY_URL && i != PARSE_DOMAIN) { hres = IInternetProtocolInfo_ParseUrl(protocol_info, javascript_test_url, i, 0, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == INET_E_DEFAULT_ACTION, "[%d] failed: %08x, expected INET_E_DEFAULT_ACTION\n", i, hres); } } hres = IInternetProtocolInfo_ParseUrl(protocol_info, javascript_test_url, PARSE_UNESCAPE+1, 0, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == INET_E_DEFAULT_ACTION, "ParseUrl failed: %08x, expected INET_E_DEFAULT_ACTION\n", hres); size = 0xdeadbeef; hres = IInternetProtocolInfo_CombineUrl(protocol_info, javascript_test_url, javascript_test_url, 0, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "CombineUrl failed: %08x\n", hres); ok(size == 0xdeadbeef, "size=%d\n", size); hres = IInternetProtocolInfo_CompareUrl(protocol_info, javascript_test_url, javascript_test_url, 0); ok(hres == E_NOTIMPL, "CompareUrl failed: %08x\n", hres); for(i=0; i<30; i++) { switch(i) { case QUERY_USES_NETWORK: case QUERY_IS_SECURE: break; default: hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, i, 0, buf, sizeof(buf), &size, 0); ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "QueryInfo(%d) returned: %08x, expected INET_E_USE_DEFAULT_PROTOCOLHANDLER\n", i, hres); } } memset(buf, '?', sizeof(buf)); hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, QUERY_USES_NETWORK, 0, buf, sizeof(buf), &size, 0); ok(hres == S_OK, "QueryInfo(QUERY_USES_NETWORK) failed: %08x\n", hres); ok(size == sizeof(DWORD), "size=%d\n", size); ok(!*(DWORD*)buf, "buf=%d\n", *(DWORD*)buf); memset(buf, '?', sizeof(buf)); hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, QUERY_USES_NETWORK, 0, buf, sizeof(buf), NULL, 0); ok(hres == S_OK, "QueryInfo(QUERY_USES_NETWORK) failed: %08x\n", hres); ok(!*(DWORD*)buf, "buf=%d\n", *(DWORD*)buf); hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, QUERY_USES_NETWORK, 0, buf, 3, &size, 0); ok(hres == E_FAIL, "QueryInfo(QUERY_USES_NETWORK) failed: %08x, expected E_FAIL\n", hres); hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, QUERY_USES_NETWORK, 0, NULL, sizeof(buf), &size, 0); ok(hres == E_FAIL, "QueryInfo(QUERY_USES_NETWORK) failed: %08x, expected E_FAIL\n", hres); hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, 60, 0, NULL, sizeof(buf), &size, 0); ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "QueryInfo failed: %08x, expected INET_E_USE_DEFAULT_PROTOCOLHANDLER\n", hres); /* FIXME: test QUERY_IS_SECURE */ IInternetProtocolInfo_Release(protocol_info); } hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory); ok(hres == S_OK, "Could not get IClassFactory interface\n"); if(SUCCEEDED(hres)) IClassFactory_Release(factory); IUnknown_Release(unk); }
long EmbedBrowserObject(HWND hwnd) { LPCLASSFACTORY pClassFactory; IOleObject *browserObject; IWebBrowser2 *webBrowser2; RECT rect; char *ptr; _IOleClientSiteEx *_iOleClientSiteEx; // Our IOleClientSite, IOleInPlaceSite, and IOleInPlaceFrame functions need to get our window handle. We // could store that in some global. But then, that would mean that our functions would work with only that // one window. If we want to create multiple windows, each hosting its own browser object (to display its // own web page), then we need to create unique IOleClientSite, IOleInPlaceSite, and IOleInPlaceFrame // structs for each window. And we'll put an extra field at the end of those structs to store our extra // data such as a window handle. So, our functions won't have to touch global data, and can therefore be // re-entrant and work with multiple objects/windows. // // Remember that a pointer to our IOleClientSite we create here will be passed as the first arg to every // one of our IOleClientSite functions. Ditto with the IOleInPlaceFrame object we create here, and the // IOleInPlaceFrame functions. So, our functions are able to retrieve the window handle we'll store here, // and then, they'll work with all such windows containing a browser control. // // Furthermore, since the browser will be calling our IOleClientSite's QueryInterface to get a pointer to // our IOleInPlaceSite and IDocHostUIHandler objects, that means that our IOleClientSite QueryInterface // must have an easy way to grab those pointers. Probably the easiest thing to do is just embed our // IOleInPlaceSite and IDocHostUIHandler objects inside of an extended IOleClientSite which we'll call // a _IOleClientSiteEx. As long as they come after the pointer to the IOleClientSite VTable, then we're // ok. // // Of course, we need to GlobalAlloc the above structs now. We'll just get all 4 with a single call to // GlobalAlloc, especially since 3 of them are all contained inside of our _IOleClientSiteEx anyway. // // So, we're not actually allocating separate IOleClientSite, IOleInPlaceSite, IOleInPlaceFrame and // IDocHostUIHandler structs. // // One final thing. We're going to allocate extra room to store the pointer to the browser object. if (!(ptr = (char *)GlobalAlloc(GMEM_FIXED, sizeof(_IOleClientSiteEx) + sizeof(IOleObject *)))) return(-1); // Initialize our IOleClientSite object with a pointer to our IOleClientSite VTable. _iOleClientSiteEx = (_IOleClientSiteEx *)(ptr + sizeof(IOleObject *)); _iOleClientSiteEx->client.lpVtbl = &gIOleClientSiteTable; // Initialize our IOleInPlaceSite object with a pointer to our IOleInPlaceSite VTable. _iOleClientSiteEx->inplace.inplace.lpVtbl = &gIOleInPlaceSiteTable; // Initialize our IOleInPlaceFrame object with a pointer to our IOleInPlaceFrame VTable. _iOleClientSiteEx->inplace.frame.frame.lpVtbl = &gIOleInPlaceFrameTable; // Save our HWND (in the IOleInPlaceFrame object) so our IOleInPlaceFrame functions can retrieve it. _iOleClientSiteEx->inplace.frame.window = hwnd; // Initialize our IDocHostUIHandler object with a pointer to our IDocHostUIHandler VTable. _iOleClientSiteEx->ui.ui.lpVtbl = &gIDocHostUIHandlerTable; // Get a pointer to the browser object and lock it down (so it doesn't "disappear" while we're using // it in this program). We do this by calling the OS function CoGetClassObject(). // // NOTE: We need this pointer to interact with and control the browser. With normal WIN32 controls such as a // Static, Edit, Combobox, etc, you obtain an HWND and send messages to it with SendMessage(). Not so with // the browser object. You need to get a pointer to its "base structure" (as returned by CoGetClassObject()). This // structure contains an array of pointers to functions you can call within the browser object. Actually, the // base structure contains a 'lpVtbl' field that is a pointer to that array. We'll call the array a 'VTable'. // // For example, the browser object happens to have a SetHostNames() function we want to call. So, after we // retrieve the pointer to the browser object (in a local we'll name 'browserObject'), then we can call that // function, and pass it args, as so: // // browserObject->lpVtbl->SetHostNames(browserObject, SomeString, SomeString); // // There's our pointer to the browser object in 'browserObject'. And there's the pointer to the browser object's // VTable in 'browserObject->lpVtbl'. And the pointer to the SetHostNames function happens to be stored in an // field named 'SetHostNames' within the VTable. So we are actually indirectly calling SetHostNames by using // a pointer to it. That's how you use a VTable. // // NOTE: We pass our _IOleClientSiteEx struct and lie -- saying that it's a IOleClientSite. It's ok. A // _IOleClientSiteEx struct starts with an embedded IOleClientSite. So the browser won't care, and we want // this extended struct passed to our IOleClientSite functions. // Get a pointer to the browser object's IClassFactory object via CoGetClassObject() pClassFactory = 0; if (!CoGetClassObject(&CLSID_WebBrowser, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, NULL, &IID_IClassFactory, (void **)&pClassFactory) && pClassFactory) { // Call the IClassFactory's CreateInstance() to create a browser object if (!pClassFactory->lpVtbl->CreateInstance(pClassFactory, 0, &IID_IOleObject, &browserObject)) { // Free the IClassFactory. We need it only to create a browser object instance pClassFactory->lpVtbl->Release(pClassFactory); // Ok, we now have the pointer to the browser object in 'browserObject'. Let's save this in the // memory block we allocated above, and then save the pointer to that whole thing in our window's // USERDATA field. That way, if we need multiple windows each hosting its own browser object, we can // call EmbedBrowserObject() for each one, and easily associate the appropriate browser object with // its matching window and its own objects containing per-window data. *((IOleObject **)ptr) = browserObject; SetWindowLong(hwnd, GWL_USERDATA, (LONG)ptr); // Give the browser a pointer to my IOleClientSite object if (!browserObject->lpVtbl->SetClientSite(browserObject, (IOleClientSite *)_iOleClientSiteEx)) { // We can now call the browser object's SetHostNames function. SetHostNames lets the browser object know our // application's name and the name of the document in which we're embedding the browser. (Since we have no // document name, we'll pass a 0 for the latter). When the browser object is opened for editing, it displays // these names in its titlebar. // // We are passing 3 args to SetHostNames. You'll note that the first arg to SetHostNames is the base // address of our browser control. This is something that you always have to remember when working in C // (as opposed to C++). When calling a VTable function, the first arg to that function must always be the // structure which contains the VTable. (In this case, that's the browser control itself). Why? That's // because that function is always assumed to be written in C++. And the first argument to any C++ function // must be its 'this' pointer (ie, the base address of its class, which in this case is our browser object // pointer). In C++, you don't have to pass this first arg, because the C++ compiler is smart enough to // produce an executable that always adds this first arg. In fact, the C++ compiler is smart enough to // know to fetch the function pointer from the VTable, so you don't even need to reference that. In other // words, the C++ equivalent code would be: // // browserObject->SetHostNames(L"My Host Name", 0); // // So, when you're trying to convert C++ code to C, always remember to add this first arg whenever you're // dealing with a VTable (ie, the field is usually named 'lpVtbl') in the standard objects, and also add // the reference to the VTable itself. // // Oh yeah, the L is because we need UNICODE strings. And BTW, the host and document names can be anything // you want. browserObject->lpVtbl->SetHostNames(browserObject, L"My Host Name", 0); GetClientRect(hwnd, &rect); // Let browser object know that it is embedded in an OLE container. if (!OleSetContainedObject((struct IUnknown *)browserObject, TRUE) && // Set the display area of our browser control the same as our window's size // and actually put the browser object into our window. !browserObject->lpVtbl->DoVerb(browserObject, OLEIVERB_SHOW, NULL, (IOleClientSite *)_iOleClientSiteEx, -1, hwnd, &rect) && // Ok, now things may seem to get even trickier, One of those function pointers in the browser's VTable is // to the QueryInterface() function. What does this function do? It lets us grab the base address of any // other object that may be embedded within the browser object. And this other object has its own VTable // containing pointers to more functions we can call for that object. // // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser // object, so we can call some of the functions in the former's table. For example, one IWebBrowser2 function // we intend to call below will be Navigate2(). So we call the browser object's QueryInterface to get our // pointer to the IWebBrowser2 object. !browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2)) { // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is // webBrowser2->lpVtbl. // Let's call several functions in the IWebBrowser2 object to position the browser display area // in our window. The functions we call are put_Left(), put_Top(), put_Width(), and put_Height(). // Note that we reference the IWebBrowser2 object's VTable to get pointers to those functions. And // also note that the first arg we pass to each is the pointer to the IWebBrowser2 object. webBrowser2->lpVtbl->put_Left(webBrowser2, 0); webBrowser2->lpVtbl->put_Top(webBrowser2, 0); webBrowser2->lpVtbl->put_Width(webBrowser2, rect.right); webBrowser2->lpVtbl->put_Height(webBrowser2, rect.bottom); // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it // right now, so we can release our hold on it). Note that we'll still maintain our hold on the // browser object until we're done with that object. webBrowser2->lpVtbl->Release(webBrowser2); // Success return(0); } } // Something went wrong setting up the browser! UnEmbedBrowserObject(hwnd); return(-4); } pClassFactory->lpVtbl->Release(pClassFactory); GlobalFree(ptr); // Can't create an instance of the browser! return(-3); } GlobalFree(ptr); // Can't get the web browser's IClassFactory! return(-2); }
static IUnknown *create_activex_object(script_ctx_t *ctx, const WCHAR *progid) { IInternetHostSecurityManager *secmgr = NULL; IObjectWithSite *obj_site; struct CONFIRMSAFETY cs; IClassFactoryEx *cfex; IClassFactory *cf; DWORD policy_size; BYTE *bpolicy; IUnknown *obj; DWORD policy; GUID guid; HRESULT hres; TRACE("%s\n", debugstr_w(progid)); hres = CLSIDFromProgID(progid, &guid); if(FAILED(hres)) return NULL; TRACE("GUID %s\n", debugstr_guid(&guid)); if(ctx->safeopt & INTERFACE_USES_SECURITY_MANAGER) { secmgr = get_sec_mgr(ctx); if(!secmgr) return NULL; policy = 0; hres = IInternetHostSecurityManager_ProcessUrlAction(secmgr, URLACTION_ACTIVEX_RUN, (BYTE*)&policy, sizeof(policy), (BYTE*)&guid, sizeof(GUID), 0, 0); if(FAILED(hres) || policy != URLPOLICY_ALLOW) return NULL; } hres = CoGetClassObject(&guid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, NULL, &IID_IClassFactory, (void**)&cf); if(FAILED(hres)) return NULL; hres = IClassFactory_QueryInterface(cf, &IID_IClassFactoryEx, (void**)&cfex); if(SUCCEEDED(hres)) { FIXME("Use IClassFactoryEx\n"); IClassFactoryEx_Release(cfex); } hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj); if(FAILED(hres)) return NULL; if(secmgr) { cs.clsid = guid; cs.pUnk = obj; cs.dwFlags = 0; hres = IInternetHostSecurityManager_QueryCustomPolicy(secmgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY, &bpolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0); if(SUCCEEDED(hres)) { policy = policy_size >= sizeof(DWORD) ? *(DWORD*)bpolicy : URLPOLICY_DISALLOW; CoTaskMemFree(bpolicy); } if(FAILED(hres) || policy != URLPOLICY_ALLOW) { IUnknown_Release(obj); return NULL; } } hres = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (void**)&obj_site); if(SUCCEEDED(hres)) { IUnknown *ax_site; ax_site = create_ax_site(ctx); if(ax_site) { hres = IObjectWithSite_SetSite(obj_site, ax_site); IUnknown_Release(ax_site); } IObjectWithSite_Release(obj_site); if(!ax_site || FAILED(hres)) { IUnknown_Release(obj); return NULL; } } return obj; }
BOOL RequestLicenseKey(BSTR& bstrLicenseKey, CString strProgID) { USES_CONVERSION; LPCLASSFACTORY2 pClassFactory; CLSID clsid; BOOL bValidKeyReturned = FALSE; // Get the CLSID of the specified ProgID if (SUCCEEDED(CLSIDFromProgID(T2OLE(strProgID), &clsid))) { // Create an instance of the object and query it for // the IClassFactory2 interface. if (SUCCEEDED(CoGetClassObject(clsid, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory2, (LPVOID *)(&pClassFactory)))) { LICINFO licinfo; // Check to see if this object has a runtime license key if (SUCCEEDED(pClassFactory->GetLicInfo(&licinfo))) { if (licinfo.fRuntimeKeyAvail) { HRESULT hr; // The object has a runtime license key so request it hr = pClassFactory->RequestLicKey(0, &bstrLicenseKey); if (SUCCEEDED(hr)) { if(bstrLicenseKey == NULL) bstrLicenseKey = ::SysAllocString( L"<Object returned a NULL license key>"); else // We got the license key! bValidKeyReturned = TRUE; } else // Requesting the license key failed switch(hr) { case E_NOTIMPL: bstrLicenseKey = ::SysAllocString( L"<The object's class factory does not support" L" run-time license keys>"); break; case E_UNEXPECTED: bstrLicenseKey = ::SysAllocString( L"<An unexpected error occurred when requesting" L" the run-time license key>"); break; case E_OUTOFMEMORY: bstrLicenseKey = ::SysAllocString( L"<The object's class factory was unable to" L" allocate the license key>"); break; case CLASS_E_NOTLICENSED: bstrLicenseKey = ::SysAllocString( L"<The object's class factory supports run-time" L" licensing, but the current machine\r\nitself" L" is not licensed. Thus, a run-time key is not" L" available on this machine>"); break; default: bstrLicenseKey = ::SysAllocString( L"<An unknown error occurred when requesting" L" the license key>"); } } else bstrLicenseKey = ::SysAllocString( L"<The object has no runtime license key>"); } else bstrLicenseKey = ::SysAllocString( L"<Unable to get the licensing capabilities of the" L" object's class factory>"); // Make sure we release the reference to the class factory pClassFactory->Release(); } else bstrLicenseKey = ::SysAllocString( L"<Unable to get the IClassFactory2 interface from the specified object>"); } else bstrLicenseKey = ::SysAllocString( L"<Unable to get the CLSID of the specified object>"); // Return a BOOL specifying whether or not we were able to get a // valid license key return bValidKeyReturned; }
int main( int argc, char *argv[] ) { printf( "Initializing COM \n"); if ( FAILED( CoInitialize( NULL ))) { printf( "Unable to initialize COM \n"); return -1; } char* szProgID = "Math.Component.1"; WCHAR szWideProgID[128]; CLSID clsid; long lLen = MultiByteToWideChar( CP_ACP, 0, szProgID,strlen( szProgID ), szWideProgID, sizeof( szWideProgID ) ); szWideProgID[ lLen ] = '\0'; HRESULT hr = ::CLSIDFromProgID( szWideProgID, &clsid ); if ( FAILED( hr )) { printf("Unable to get CLSID from ProgID. HR = %X \n",hr); return -1; } IClassFactory* pCF; // Получить фабрику класса для CMath hr = CoGetClassObject( clsid, CLSCTX_INPROC, NULL,IID_IClassFactory, (void**) &pCF ); if ( FAILED( hr )) { printf("Failed to GetClassObject server instance. HR = %X \n",hr); return -1; } // с помощью фабрики класса создать экземпляр // компонента и получить интерфейс IUnknown. IUnknown* pUnk; hr = pCF->CreateInstance( NULL, IID_IUnknown, (void**) &pUnk ); // Release the class factory pCF->Release(); if ( FAILED( hr )) { printf("Failed to create server instance. HR =%X \n",hr); return -1; } printf("Instance created \n"); IMath* pMath = NULL; hr = pUnk->QueryInterface( IID_IMath, (LPVOID*)&pMath ); pUnk->Release(); if ( FAILED( hr )) { printf("QueryInterface() for IMath failed \n"); return -1; } long result; pMath->Add(255,125,&result); printf("Func - Add: 255 + 125 is %d \n",result); pMath->Multiply( 30, 8, &result ); printf("Func - Mltiply: 30 * 8 is %d \n",result); pMath->Subtract( 200, 123, &result ); printf("Func - Substract: 200 - 123 is %d \n",result); pMath->Divide(21,3,&result); printf("Func - Divide: 21 / 3 is %d \n",result); printf("Releasing instance \n"); pMath->Release(); printf("Shuting down COM\n"); CoUninitialize(); _getch(); return 0; }
static void IDirectSound8_tests(void) { HRESULT rc; LPDIRECTSOUND8 dso=NULL; LPCLASSFACTORY cf=NULL; trace("Testing IDirectSound8\n"); rc=CoGetClassObject(&CLSID_DirectSound8, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&cf); ok(rc==S_OK,"CoGetClassObject(CLSID_DirectSound8, IID_IClassFactory) " "failed: %08x\n", rc); rc=CoGetClassObject(&CLSID_DirectSound8, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&cf); ok(rc==S_OK,"CoGetClassObject(CLSID_DirectSound8, IID_IUnknown) " "failed: %08x\n", rc); /* try the COM class factory method of creation with no device specified */ rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void**)&dso); ok(rc==S_OK||rc==REGDB_E_CLASSNOTREG,"CoCreateInstance() failed: %08x\n", rc); if (rc==REGDB_E_CLASSNOTREG) { trace(" Class Not Registered\n"); return; } if (dso) IDirectSound8_test(dso, FALSE, NULL); /* try the COM class factory method of creation with default playback * device specified */ rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void**)&dso); ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %08x\n", rc); if (dso) IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultPlayback); /* try the COM class factory method of creation with default voice * playback device specified */ rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void**)&dso); ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %08x\n", rc); if (dso) IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback); /* try the COM class factory method of creation with a bad * IID specified */ rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &CLSID_DirectSoundPrivate, (void**)&dso); ok(rc==E_NOINTERFACE, "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) " "should have failed: %08x\n",rc); /* try the COM class factory method of creation with a bad * GUID and IID specified */ rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void**)&dso); ok(rc==REGDB_E_CLASSNOTREG, "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) " "should have failed: %08x\n",rc); /* try with no device specified */ rc=pDirectSoundCreate8(NULL,&dso,NULL); ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, "DirectSoundCreate8() failed: %08x\n",rc); if (rc==DS_OK && dso) IDirectSound8_test(dso, TRUE, NULL); /* try with default playback device specified */ rc=pDirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL); ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, "DirectSoundCreate8() failed: %08x\n",rc); if (rc==DS_OK && dso) IDirectSound8_test(dso, TRUE, NULL); /* try with default voice playback device specified */ rc=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL); ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, "DirectSoundCreate8() failed: %08x\n",rc); if (rc==DS_OK && dso) IDirectSound8_test(dso, TRUE, NULL); /* try with a bad device specified */ rc=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL); ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) " "should have failed: %08x\n",rc); }