HRESULT FakeContent::GetValue( REFPROPERTYKEY Key, __out IPortableDeviceValues* pStore) { HRESULT hr = S_OK; PropVariantWrapper pvValue; if(pStore == NULL) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } if (IsEqualPropertyKey(Key, WPD_OBJECT_ID)) { // Add WPD_OBJECT_ID pvValue = ObjectID; hr = pStore->SetValue(WPD_OBJECT_ID, &pvValue); CHECK_HR(hr, ("Failed to set WPD_OBJECT_ID")); } else if (IsEqualPropertyKey(Key, WPD_OBJECT_PERSISTENT_UNIQUE_ID)) { // Add WPD_OBJECT_PERSISTENT_UNIQUE_ID pvValue = this->PersistentUniqueID; hr = pStore->SetValue(WPD_OBJECT_PERSISTENT_UNIQUE_ID, &pvValue); CHECK_HR(hr, ("Failed to set WPD_OBJECT_PERSISTENT_UNIQUE_ID")); } else if (IsEqualPropertyKey(Key, WPD_OBJECT_PARENT_ID)) { // Add WPD_OBJECT_PARENT_ID pvValue = ParentID; hr = pStore->SetValue(WPD_OBJECT_PARENT_ID, &pvValue); CHECK_HR(hr, ("Failed to set WPD_OBJECT_PARENT_ID")); } else if (IsEqualPropertyKey(Key, WPD_OBJECT_NAME)) { // Add WPD_OBJECT_NAME pvValue = Name; hr = pStore->SetValue(WPD_OBJECT_NAME, &pvValue); CHECK_HR(hr, ("Failed to set WPD_OBJECT_NAME")); } else if (IsEqualPropertyKey(Key, WPD_OBJECT_CONTENT_TYPE)) { // Add WPD_OBJECT_CONTENT_TYPE hr = pStore->SetGuidValue(WPD_OBJECT_CONTENT_TYPE, ContentType); CHECK_HR(hr, ("Failed to set WPD_OBJECT_CONTENT_TYPE")); } else if (IsEqualPropertyKey(Key, WPD_OBJECT_FORMAT)) { // Add WPD_OBJECT_FORMAT hr = pStore->SetGuidValue(WPD_OBJECT_FORMAT, Format); CHECK_HR(hr, ("Failed to set WPD_OBJECT_FORMAT")); } else if (IsEqualPropertyKey(Key, WPD_OBJECT_CAN_DELETE)) { // Add WPD_OBJECT_CAN_DELETE hr = pStore->SetBoolValue(WPD_OBJECT_CAN_DELETE, CanDelete); CHECK_HR(hr, ("Failed to set WPD_OBJECT_CAN_DELETE")); } else { hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); CHECK_HR(hr, "Property {%ws}.%d is not supported", CComBSTR(Key.fmtid), Key.pid); } return hr; }
//--------------------------------------------------------------------------- // wxActiveXContainer::CreateActiveX // // Actually creates the ActiveX container through the FrameSite // and sets up ActiveX events // // TODO: Document this more //--------------------------------------------------------------------------- void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk) { HRESULT hret; hret = m_ActiveX.QueryInterface(iid, pUnk); CHECK_HR(hret); // FrameSite m_frameSite = new FrameSite(m_realparent, this); // oleClientSite hret = m_clientSite.QueryInterface( IID_IOleClientSite, (IDispatch *) m_frameSite); CHECK_HR(hret); // adviseSink wxAutoIAdviseSink adviseSink(IID_IAdviseSink, (IDispatch *) m_frameSite); wxASSERT(adviseSink.IsOk()); // Get Dispatch interface hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX); CHECK_HR(hret); // // SETUP TYPEINFO AND ACTIVEX EVENTS // // get type info via class info wxAutoIProvideClassInfo classInfo(IID_IProvideClassInfo, m_ActiveX); wxASSERT(classInfo.IsOk()); // type info wxAutoITypeInfo typeInfo; hret = classInfo->GetClassInfo(typeInfo.GetRef()); CHECK_HR(hret); wxASSERT(typeInfo.IsOk()); // TYPEATTR TYPEATTR *ta = NULL; hret = typeInfo->GetTypeAttr(&ta); CHECK_HR(hret); // this should be a TKIND_COCLASS wxASSERT(ta->typekind == TKIND_COCLASS); // iterate contained interfaces for (int i = 0; i < ta->cImplTypes; i++) { HREFTYPE rt = 0; // get dispatch type info handle hret = typeInfo->GetRefTypeOfImplType(i, &rt); if (! SUCCEEDED(hret)) continue; // get dispatch type info interface wxAutoITypeInfo ti; hret = typeInfo->GetRefTypeInfo(rt, ti.GetRef()); if (! ti.IsOk()) continue; CHECK_HR(hret); // check if default event sink bool defEventSink = false; int impTypeFlags = 0; typeInfo->GetImplTypeFlags(i, &impTypeFlags); if (impTypeFlags & IMPLTYPEFLAG_FDEFAULT) { if (impTypeFlags & IMPLTYPEFLAG_FSOURCE) { // WXOLE_TRACEOUT("Default Event Sink"); defEventSink = true; if (impTypeFlags & IMPLTYPEFLAG_FDEFAULTVTABLE) { // WXOLE_TRACEOUT("*ERROR* - Default Event Sink is via vTable"); defEventSink = false; wxFAIL_MSG(wxT("Default event sink is in vtable!")); } } } // wxAutoOleInterface<> assumes a ref has already been added // TYPEATTR TYPEATTR *ta = NULL; hret = ti->GetTypeAttr(&ta); CHECK_HR(hret); if (ta->typekind == TKIND_DISPATCH) { // WXOLE_TRACEOUT("GUID = " << GetIIDName(ta->guid).c_str()); if (defEventSink) { wxAutoIConnectionPoint cp; DWORD adviseCookie = 0; wxAutoIConnectionPointContainer cpContainer(IID_IConnectionPointContainer, m_ActiveX); wxASSERT( cpContainer.IsOk()); HRESULT hret = cpContainer->FindConnectionPoint(ta->guid, cp.GetRef()); // Notice that the return value of CONNECT_E_NOCONNECTION is // expected if the interface doesn't support connection points. if ( hret != CONNECT_E_NOCONNECTION ) { CHECK_HR(hret); } if ( cp ) { wxActiveXEvents * const events = new wxActiveXEvents(this, ta->guid); hret = cp->Advise(events, &adviseCookie); // We don't need this object any more and cp will keep a // reference to it if it needs it, i.e. if Advise() // succeeded. events->Release(); CHECK_HR(hret); } } } ti->ReleaseTypeAttr(ta); } // free typeInfo->ReleaseTypeAttr(ta); // // END // // Get IOleObject interface hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX); CHECK_HR(hret); // get IViewObject Interface hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX); CHECK_HR(hret); // document advise m_docAdviseCookie = 0; hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie); CHECK_HR(hret); // TODO:Needed? // hret = m_viewObject->SetAdvise(DVASPECT_CONTENT, 0, adviseSink); m_oleObject->SetHostNames(L"wxActiveXContainer", NULL); OleSetContainedObject(m_oleObject, TRUE); OleRun(m_oleObject); // Get IOleInPlaceObject interface hret = m_oleInPlaceObject.QueryInterface( IID_IOleInPlaceObject, m_ActiveX); CHECK_HR(hret); // status DWORD dwMiscStatus; m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus); CHECK_HR(hret); // set client site first ? if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST) m_oleObject->SetClientSite(m_clientSite); // stream init wxAutoIPersistStreamInit pPersistStreamInit(IID_IPersistStreamInit, m_oleObject); if (pPersistStreamInit.IsOk()) { hret = pPersistStreamInit->InitNew(); CHECK_HR(hret); } if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)) m_oleObject->SetClientSite(m_clientSite); m_oleObjectHWND = 0; if (m_oleInPlaceObject.IsOk()) { hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND); if (SUCCEEDED(hret)) ::SetActiveWindow(m_oleObjectHWND); } if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME)) { RECT posRect; wxCopyRectToRECT(m_realparent->GetClientSize(), posRect); if (posRect.right > 0 && posRect.bottom > 0 && m_oleInPlaceObject.IsOk()) { m_oleInPlaceObject->SetObjectRects(&posRect, &posRect); } hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect); CHECK_HR(hret); hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect); CHECK_HR(hret); } if (! m_oleObjectHWND && m_oleInPlaceObject.IsOk()) { hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND); CHECK_HR(hret); } if (m_oleObjectHWND) { ::SetActiveWindow(m_oleObjectHWND); ::ShowWindow(m_oleObjectHWND, SW_SHOW); this->AssociateHandle(m_oleObjectHWND); this->Reparent(m_realparent); wxWindow* pWnd = m_realparent; int id = m_realparent->GetId(); pWnd->Connect(id, wxEVT_SIZE, wxSizeEventHandler(wxActiveXContainer::OnSize), 0, this); // this->Connect(GetId(), wxEVT_PAINT, // wxPaintEventHandler(wxActiveXContainer::OnPaint), 0, this); pWnd->Connect(id, wxEVT_SET_FOCUS, wxFocusEventHandler(wxActiveXContainer::OnSetFocus), 0, this); pWnd->Connect(id, wxEVT_KILL_FOCUS, wxFocusEventHandler(wxActiveXContainer::OnKillFocus), 0, this); } }
HRESULT StaticSourceVideoPin::FillBuffer(IMediaSample * pSample) { CheckPointer(pSample, E_POINTER); HRESULT hr = S_OK; DWORD frameDataCount; BYTE * frameData; //Nastavenie hodnoty casu zaciatku a konca snimky REFERENCE_TIME rtStart = this->m_rtLastFrame; REFERENCE_TIME rtStop = rtStart + this->m_pFilter->m_params->m_rtFrameLength; pSample->SetTime(&rtStart, &rtStop); if (this->m_pFilter->m_rtStop > 0 && rtStop >= this->m_pFilter->m_rtStop) { //Ak je nastaveny cas konca a prekroci sa, ukonci sa stream hr = S_FALSE; goto done; } this->m_rtLastFrame = rtStop; CHECK_HR(hr = pSample->GetPointer(&frameData)); frameDataCount = pSample->GetSize(); //Ak je nastavena bitmapa, pouzi tu, inak nastav sum if (this->m_pFilter->m_params->m_bitmapData == NULL) { for (DWORD i = 0; i < frameDataCount; i++) frameData[i] = (BYTE)(rand() % 256); } else { if (this->m_mt.subtype == MEDIASUBTYPE_RGB32) { //Na vystup ide RGB32 typ if (this->m_pFilter->m_params->m_bitmapInfo.biBitCount == 32) { CopyMemory(frameData, this->m_pFilter->m_params->m_bitmapData, frameDataCount); } else { BITMAPINFOHEADER dstBmi = this->m_pFilter->m_params->m_bitmapInfo; dstBmi.biBitCount = 32; RGBtoRGB(this->m_pFilter->m_params->m_bitmapInfo, this->m_pFilter->m_params->m_bitmapData, frameData, dstBmi); } } else if (this->m_mt.subtype == MEDIASUBTYPE_RGB24) { //Na vystup ide RGB24 typ if (this->m_pFilter->m_params->m_bitmapInfo.biBitCount == 24) { CopyMemory(frameData, this->m_pFilter->m_params->m_bitmapData, frameDataCount); } else { BITMAPINFOHEADER dstBmi = this->m_pFilter->m_params->m_bitmapInfo; dstBmi.biBitCount = 24; RGBtoRGB(this->m_pFilter->m_params->m_bitmapInfo, this->m_pFilter->m_params->m_bitmapData, frameData, dstBmi); } } else if (this->m_mt.subtype == MEDIASUBTYPE_YUY2) { //Na vystup ide YUY2 typ RGBtoYUY2(this->m_pFilter->m_params->m_bitmapInfo, this->m_pFilter->m_params->m_bitmapData, frameData); } else if (this->m_mt.subtype == MEDIASUBTYPE_YV12) { //Na vystup ide YV12 typ RGBtoYV12(this->m_pFilter->m_params->m_bitmapInfo, this->m_pFilter->m_params->m_bitmapData, frameData); } } CHECK_HR(hr = pSample->SetSyncPoint(TRUE)); CHECK_HR(hr = pSample->SetActualDataLength(frameDataCount)); done: return hr; }
/** * This method is called when we receive a WPD_COMMAND_OBJECT_RESOURCES_READ * command. * * The parameters sent to us are: * - WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT: the context the driver returned to * the client in OnOpenResource. * - WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_READ: the number of bytes to * read from the resource. * * The driver should: * - Read data associated with the resource and return it back to the caller in * WPD_PROPERTY_OBJECT_RESOURCES_DATA. * - Report the number of bytes actually read from the resource in * WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_READ. This number may be smaller * than WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_READ when reading the last * chunk of data from the resource. */ HRESULT WpdObjectResources::OnReadResource( _In_ IPortableDeviceValues* pParams, _In_ IPortableDeviceValues* pResults) { HRESULT hr = S_OK; LPWSTR wszResourceContext = NULL; DWORD dwNumBytesToRead = 0; DWORD dwNumBytesRead = 0; BYTE* pBuffer = NULL; WpdObjectResourceContext* pResourceContext = NULL; ContextMap* pContextMap = NULL; // Get the enumeration context identifier for this enumeration operation. We will // need this to lookup the specific enumeration context in the client context map. hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT, &wszResourceContext); if (hr != S_OK) { hr = E_INVALIDARG; CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT"); } // Get the number of bytes to read if (hr == S_OK) { hr = pParams->GetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_READ, &dwNumBytesToRead); CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_READ"); } // Allocate the destination buffer if (hr == S_OK) { pBuffer = reinterpret_cast<BYTE *>(CoTaskMemAlloc(dwNumBytesToRead)); if (pBuffer == NULL) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate the destination buffer"); } } // Get the client context map so we can retrieve the resource context for this resource // operation using the WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT property value obtained above. if (hr == S_OK) { hr = pParams->GetIUnknownValue(PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP, (IUnknown**)&pContextMap); CHECK_HR(hr, "Failed to get PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP"); } if (hr == S_OK) { pResourceContext = (WpdObjectResourceContext*)pContextMap->GetContext(wszResourceContext); if (pResourceContext == NULL) { hr = E_INVALIDARG; CHECK_HR(hr, "Missing resource context"); } } // Read the next chunk of data for this request if (hr == S_OK && pBuffer != NULL) { hr = ReadDataFromResource(pResourceContext, pBuffer, dwNumBytesToRead, &dwNumBytesRead); CHECK_HR(hr, "Failed to read %d bytes from resource", dwNumBytesToRead); } if (hr == S_OK && pBuffer != NULL) { hr = pResults->SetBufferValue(WPD_PROPERTY_OBJECT_RESOURCES_DATA, pBuffer, dwNumBytesRead); CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_DATA"); } if (hr == S_OK) { hr = pResults->SetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_READ, dwNumBytesRead); CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_READ"); } // Free the memory. CoTaskMemFree ignores NULLs so no need to check. CoTaskMemFree(wszResourceContext); // Free the memory. CoTaskMemFree ignores NULLs so no need to check. CoTaskMemFree(pBuffer); SAFE_RELEASE(pContextMap); return hr; }
int main() { UINT dpi = SetupDPI(); gRenderScale = 96.0 / double(dpi); // Scale default window size based on dpi gWindowWidth *= dpi / 96; gWindowHeight *= dpi / 96; // Create window { WNDCLASSEX wc; ZeroMemory(&wc, sizeof(wc)); wc.cbSize = sizeof(wc); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = MyWndProc; wc.hInstance = GetModuleHandle(NULL); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND; wc.lpszClassName = TEXT("WindowClass"); CHECK_WIN32(RegisterClassEx(&wc)); RECT wr = { 0, 0, gWindowWidth, gWindowHeight }; CHECK_WIN32(AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE)); ghWnd = CHECK_WIN32(CreateWindowEx( 0, TEXT("WindowClass"), TEXT("Spooky"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top, 0, 0, GetModuleHandle(NULL), 0)); } // Create D3D11 device and swap chain { ComPtr<IDXGIFactory> pFactory; CHECK_HR(CreateDXGIFactory(IID_PPV_ARGS(&pFactory))); UINT deviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; #ifdef _DEBUG deviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif RECT clientRect; GetClientRect(ghWnd, &clientRect); DXGI_SWAP_CHAIN_DESC scd{}; scd.BufferCount = kSwapChainBufferCount; scd.BufferDesc.Format = kSwapChainFormat; scd.BufferDesc.Width = clientRect.right - clientRect.left; scd.BufferDesc.Height = clientRect.bottom - clientRect.top; scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scd.OutputWindow = ghWnd; scd.Windowed = TRUE; scd.SampleDesc.Count = 1; scd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; CHECK_HR(D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, deviceFlags, NULL, 0, D3D11_SDK_VERSION, &scd, &gpSwapChain, &gpDevice, NULL, &gpDeviceContext)); CHECK_HR(gpDevice.As(&gpDxgiDevice)); } InitApp(dpi); ShowWindow(ghWnd, SW_SHOWNORMAL); EnableMouseInPointer(TRUE); while (!gShouldClose) { // Handle all events MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } UpdateApp(); RenderApp(); // Swap buffers CHECK_HR(gpSwapChain->Present(0, 0)); } CoUninitialize(); // <- this currently creates problems with the WIC Factory. CHECK_HR(gpSwapChain->SetFullscreenState(FALSE, NULL)); }
/** * This method is called when we receive a WPD_COMMAND_OBJECT_PROPERTIES_BULK_SET_VALUES_BY_OBJECT_LIST_NEXT * command. * * The parameters sent to us are: * - WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT: the context the driver returned to * the client in OnGetValuesByObjectListStart. * * The driver should: * - Write the next set of property values, and return the write results in WPD_PROPERTY_OBJECT_PROPERTIES_BULK_WRITE_RESULTS. * If there are no more properties to be written, an empty collection should be returned. * - It is up to the driver to write as many object property values as it wants. If zero write results are returned * it is assumed the bulk operation is complete and the WPD_COMMAND_OBJECT_PROPERTIES_BULK_SET_VALUES_BY_OBJECT_LIST_END * will be called next. * * - S_OK should be returned if the collection can be returned successfully. * - Any error return indicates that the driver did not fill in any results, and the caller will * not attempt to unpack any property values. */ HRESULT WpdObjectPropertiesBulk::OnSetValuesByObjectListNext( _In_ IPortableDeviceValues* pParams, _In_ IPortableDeviceValues* pResults) { HRESULT hr = S_OK; LPWSTR pwszContext = NULL; BulkPropertiesContext* pContext = NULL; DWORD cObjects = 0; CComPtr<IPortableDeviceValues> pEventParams; CComPtr<IPortableDeviceValuesCollection> pWriteResults; CComPtr<IPortableDeviceValuesCollection> pValuesCollection; hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT, &pwszContext); CHECK_HR(hr, "Failed to get WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT from IPortableDeviceValues"); // Get the bulk property operation context if (SUCCEEDED(hr)) { hr = GetClientContext(pParams, pwszContext, (IUnknown**) &pContext); CHECK_HR(hr, "Failed to get bulk property context"); } // Make sure the the collection holds a ValuesCollection, then get the number of elements. if (SUCCEEDED(hr)) { if(pContext->ValuesCollection != NULL) { hr = pContext->ValuesCollection->GetCount(&cObjects); CHECK_HR(hr, "Failed to get number of objectIDs from bulk properties context"); } else { hr = E_INVALIDARG; CHECK_HR(hr, "Incorrect context specified - this context does not contain a values collection"); } } // Create the collection to hold the write results if (SUCCEEDED(hr)) { hr = CoCreateInstance(CLSID_PortableDeviceValuesCollection, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValuesCollection, (VOID**) &pWriteResults); CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValuesCollection"); } // Create the collection to hold the event parameters if (SUCCEEDED(hr)) { hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**) &pEventParams); CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues"); } if (SUCCEEDED(hr)) { for (DWORD dwIndex = pContext->NextObject; dwIndex < cObjects; dwIndex++) { CComPtr<IPortableDeviceValues> pValues; CComPtr<IPortableDeviceValues> pSetResults; bool bObjectChanged = false; hr = pContext->ValuesCollection->GetAt(dwIndex, &pValues); CHECK_HR(hr, "Failed to get next values from bulk properties context"); // CoCreate a collection to store the per object results. if (SUCCEEDED(hr)) { hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**) &pSetResults); CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues"); } if (SUCCEEDED(hr)) { LPWSTR pszObjectID = NULL; // Get which object this is for hr = pValues->GetStringValue(WPD_OBJECT_ID, &pszObjectID); if (SUCCEEDED(hr)) { hr = m_pDevice->SetPropertyValues(pContext->Scope, pszObjectID, pValues, pSetResults, pEventParams, &bObjectChanged); CHECK_HR(hr, "Failed to get count of values"); } if (SUCCEEDED(hr)) { // Ensure the write results contain which ObjectID this was for hr = pSetResults->SetStringValue(WPD_OBJECT_ID, pszObjectID); CHECK_HR(hr, "Failed to set WPD_OBJECT_ID in write results"); if (SUCCEEDED(hr) && bObjectChanged) { // set property values is successful and object has changed, so we post an event. // This is best effort, so errors are ignored HRESULT hrEvent = PostWpdEvent(pParams, pEventParams); CHECK_HR(hrEvent, "Failed post event for updated object [%ws] (errors ignored)", pszObjectID); } pEventParams->Clear(); } CoTaskMemFree(pszObjectID); } if (SUCCEEDED(hr)) { hr = pWriteResults->Add(pSetResults); CHECK_HR(hr, "Failed to add IPortableDeviceValues to IPortableDeviceValuesCollection"); } pContext->NextObject++; } } if (SUCCEEDED(hr)) { hr = pResults->SetIUnknownValue(WPD_PROPERTY_OBJECT_PROPERTIES_BULK_WRITE_RESULTS, pWriteResults); CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_PROPERTIES_BULK_WRITE_RESULTS"); } // Free the memory. CoTaskMemFree ignores NULLs so no need to check. CoTaskMemFree(pwszContext); SAFE_RELEASE(pContext); return hr; }
HRESULT WpdServiceMethods::DispatchMethod( _In_ LPCWSTR pwszContext, _In_ IPortableDeviceValues* pStartParams, _Outptr_ IPortableDeviceValues** ppResults) { HRESULT hr = S_OK; HRESULT hrStatus = S_OK; GUID Method = GUID_NULL; CComPtr<IPortableDeviceValues> pMethodParams; CComPtr<IPortableDeviceValues> pMethodResults; *ppResults = NULL; // Get the method GUID hr = pStartParams->GetGuidValue(WPD_PROPERTY_SERVICE_METHOD, &Method); CHECK_HR(hr, "Failed to get WPD_PROPERTY_SERVICE_METHOD"); // Get the method parameters. These can be optional if the methods don't require parameters if (hr == S_OK) { HRESULT hrTemp = pStartParams->GetIPortableDeviceValuesValue(WPD_PROPERTY_SERVICE_METHOD_PARAMETER_VALUES, &pMethodParams); CHECK_HR(hrTemp, "Failed to get WPD_PROPERTY_SERVICE_METHOD_PARAMETER_VALUES (ok if method does not require parameters)"); } // Prepare the results collection if (hr == S_OK) { hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**)ppResults); CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues"); } if (hr == S_OK) { // Invoke the method to the service m_pGattService->OnMethodInvoke(Method, pMethodParams, *ppResults); } // Post the completion event if the method has failed. { if (hr == S_OK) { hr = (*ppResults)->SetGuidValue(WPD_EVENT_PARAMETER_EVENT_ID, WPD_EVENT_SERVICE_METHOD_COMPLETE); CHECK_HR(hr, "Failed to set the event id to WPD_EVENT_SERVICE_METHOD_COMPLETE"); } if (hr == S_OK) { hr = (*ppResults)->SetStringValue(WPD_EVENT_PARAMETER_SERVICE_METHOD_CONTEXT, pwszContext); CHECK_HR(hr, "Failed to set the method context for WPD_EVENT_SERVICE_METHOD_COMPLETE"); } if (hr == S_OK) { hr = PostWpdEvent(pStartParams, *ppResults); CHECK_HR(hr, "Failed to post WPD_EVENT_SERVICE_METHOD_COMPLETE"); } } if (hr == S_OK) { hr = hrStatus; } return hr; }
///////////////////////////////////////////////////////////////// // myGetProperty // // This function gets the BOOL value for the specified property // and returns the result in *pbValue. // ///////////////////////////////////////////////////////////////// HRESULT myGetProperty ( IUnknown * pIUnknown, REFIID riid, DBPROPID dwPropertyID, REFGUID guidPropertySet, BOOL * pbValue ) { HRESULT hr; DBPROPID rgPropertyIDs[1]; DBPROPIDSET rgPropertyIDSets[1]; ULONG cPropSets = 0; DBPROPSET * rgPropSets = NULL; IDBProperties * pIDBProperties = NULL; ISessionProperties * pISesProps = NULL; ICommandProperties * pICmdProps = NULL; IRowsetInfo * pIRowsetInfo = NULL; // Initialize the output value *pbValue = FALSE; // Set up the property ID array rgPropertyIDs[0] = dwPropertyID; // Set up the Property ID Set rgPropertyIDSets[0].rgPropertyIDs = rgPropertyIDs; rgPropertyIDSets[0].cPropertyIDs = 1; rgPropertyIDSets[0].guidPropertySet = guidPropertySet; // Get the property value for this property from the provider, but // don't try to display extended error information, since this may // not be a supported property: a failure is, in fact, expected if // the property is not supported if( riid == IID_IDBProperties ) { XCHECK_HR(hr = pIUnknown->QueryInterface(IID_IDBProperties, (void**)&pIDBProperties)); CHECK_HR(hr = pIDBProperties->GetProperties( 1, //cPropertyIDSets rgPropertyIDSets, //rgPropertyIDSets &cPropSets, //pcPropSets &rgPropSets //prgPropSets )); } else if( riid == IID_ISessionProperties ) { XCHECK_HR(hr = pIUnknown->QueryInterface(IID_ISessionProperties, (void**)&pISesProps)); CHECK_HR(hr = pISesProps->GetProperties( 1, //cPropertyIDSets rgPropertyIDSets, //rgPropertyIDSets &cPropSets, //pcPropSets &rgPropSets //prgPropSets )); } else if( riid == IID_ICommandProperties ) { XCHECK_HR(hr = pIUnknown->QueryInterface(IID_ICommandProperties, (void**)&pICmdProps)); CHECK_HR(hr = pICmdProps->GetProperties( 1, //cPropertyIDSets rgPropertyIDSets, //rgPropertyIDSets &cPropSets, //pcPropSets &rgPropSets //prgPropSets )); } else { XCHECK_HR(hr = pIUnknown->QueryInterface(IID_IRowsetInfo, (void**)&pIRowsetInfo)); CHECK_HR(hr = pIRowsetInfo->GetProperties( 1, //cPropertyIDSets rgPropertyIDSets, //rgPropertyIDSets &cPropSets, //pcPropSets &rgPropSets //prgPropSets )); } // Return the value for this property to the caller if // it's a VT_BOOL type value, as expected if( V_VT(&rgPropSets[0].rgProperties[0].vValue) == VT_BOOL ) *pbValue = V_BOOL(&rgPropSets[0].rgProperties[0].vValue); CLEANUP: if( rgPropSets ) { CoTaskMemFree(rgPropSets[0].rgProperties); CoTaskMemFree(rgPropSets); } if( pIDBProperties ) pIDBProperties->Release(); if( pISesProps ) pISesProps->Release(); if( pICmdProps ) pICmdProps->Release(); if( pIRowsetInfo ) pIRowsetInfo->Release(); return hr; }
///////////////////////////////////////////////////////////////// // myCreateDataSource // // This function creates an OLE DB DataSource object for a // provider selected by the user, sets initialization properties // for the DataSource, and initializes the DataSource. The // function returns a pointer to the DataSource object's // IUnknown in *ppUnkDataSource. // ///////////////////////////////////////////////////////////////// HRESULT myCreateDataSource ( IUnknown ** ppUnkDataSource ) { HRESULT hr; IDataInitialize * pIDataInitialize = NULL; IDBPromptInitialize * pIDBPromptInitialize = NULL; IDBInitialize * pIDBInitialize = NULL; CLSID clsid = CLSID_MSDASQL; // Use the Microsoft Data Links UI to create the DataSource // object; this will allow the user to select the provider // to connect to and to set the initialization properties // for the DataSource object, which will be created by the // Data Links UI. if( g_dwFlags & USE_PROMPTDATASOURCE ) { // Create the Data Links UI object and obtain the // IDBPromptInitialize interface from it XCHECK_HR(hr = CoCreateInstance( CLSID_DataLinks, //clsid -- Data Links UI NULL, //pUnkOuter CLSCTX_INPROC_SERVER, //dwClsContext IID_IDBPromptInitialize, //riid (void**)&pIDBPromptInitialize //ppvObj )); // Invoke the Data Links UI to allow the user to select // the provider and set initialization properties for // the DataSource object that this will create XCHECK_HR(hr = pIDBPromptInitialize->PromptDataSource( NULL, //pUnkOuter GetDesktopWindow(), //hWndParent DBPROMPTOPTIONS_PROPERTYSHEET, //dwPromptOptions 0, //cSourceTypeFilter NULL, //rgSourceTypeFilter NULL, //pwszszzProviderFilter IID_IDBInitialize, //riid (IUnknown**)&pIDBInitialize //ppDataSource )); // We've obtained a DataSource object from the Data Links UI. This // object has had its initialization properties set, so all we // need to do is Initialize it XCHECK_HR(hr = pIDBInitialize->Initialize()); } // We are not using the Data Links UI to create the DataSource object. // Instead, we will enumerate the providers installed on this system // through the OLE DB Enumerator and will allow the user to select // the ProgID of the provider for which we will create a DataSource // object. else { // Use the OLE DB Enumerator to obtain a rowset of installed providers, // then allow the user to select a provider from this rowset CHECK_HR(hr = myCreateEnumerator(CLSID_OLEDB_ENUMERATOR, &clsid)); // We will create the DataSource object through the OLE DB service // component IDataInitialize interface, so we need to create an // instance of the data initialization object XCHECK_HR(hr = CoCreateInstance( CLSID_MSDAINITIALIZE, //clsid -- data initialize NULL, //pUnkOuter CLSCTX_INPROC_SERVER, //dwClsContext IID_IDataInitialize, //riid (void**)&pIDataInitialize //ppvObj )); // Use IDataInitialize::CreateDBInstance to create an uninitialized // DataSource object for the chosen provider. By using this service // component method, the service component manager can provide // additional functionality beyond what is natively supported by the // provider if the consumer requests that functionality XCHECK_HR(hr = pIDataInitialize->CreateDBInstance( clsid, //clsid -- provider NULL, //pUnkOuter CLSCTX_INPROC_SERVER, //dwClsContext NULL, //pwszReserved IID_IDBInitialize, //riid (IUnknown**)&pIDBInitialize //ppDataSource )); // Initialize the DataSource object by setting any required // initialization properties and calling IDBInitialize::Initialize CHECK_HR(hr = myDoInitialization(pIDBInitialize)); } CLEANUP: *ppUnkDataSource = pIDBInitialize; if( pIDataInitialize ) pIDataInitialize->Release(); if( pIDBPromptInitialize ) pIDBPromptInitialize->Release(); return hr; }
/*----------------------------------------------------------------------------- FUNCTION: SetPortState( void ) PURPOSE: Sets port state based on settings from the user COMMENTS: Sets up DCB structure and calls SetCommState. Sets up new timeouts by calling SetCommTimeouts. HISTORY: Date: Author: Comment: 1/9/96 AllenD Wrote it 12/06/06 DonnMo Replaced calls to ErrorReporter() with CHECK_HR() -----------------------------------------------------------------------------*/ HRESULT RS232Connection::SetPortState() { HRESULT hr = S_OK; DCB dcb = {0}; DWORD dwLastError = 0; dcb.DCBlength = sizeof(dcb); // // get current DCB settings // if (!GetCommState(m_hCommPort, &dcb)) { dwLastError = GetLastError(); hr = HRESULT_FROM_WIN32(dwLastError); CHECK_HR(hr, "GetCommState() failed within SetPortState()."); return hr; } // // update DCB rate, byte size, parity, and stop bits size // dcb.BaudRate = m_dwBaudRate; dcb.ByteSize = m_bByteSize; dcb.Parity = m_bParity; dcb.StopBits = m_bStopBits; // // update event flags // if (m_dwEventFlags & EV_RXFLAG) { dcb.EvtChar = m_chFlag; } else { dcb.EvtChar = '\0'; } dcb.EofChar = '\n'; // // update flow control settings // dcb.fDtrControl = m_fDtrControl; dcb.fRtsControl = m_fRtsControl; dcb.fOutxCtsFlow = m_fCTSOutFlow; dcb.fOutxDsrFlow = m_fDSROutFlow; dcb.fDsrSensitivity = m_fDSRInFlow; dcb.fOutX = m_fXonXoffOutFlow; dcb.fInX = m_fXonXoffInFlow; dcb.fTXContinueOnXoff = m_fTXafterXoffSent; dcb.XonChar = m_chXON; dcb.XoffChar = m_chXOFF; dcb.XonLim = m_wXONLimit; dcb.XoffLim = m_wXOFFLimit; // // DCB settings not in the user's control // dcb.fParity = TRUE; // // set new state // if (!SetCommState(m_hCommPort, &dcb)) { dwLastError = GetLastError(); hr = HRESULT_FROM_WIN32(dwLastError); CHECK_HR(hr, "SetCommState() failed within SetPortState() when setting the new state."); return hr; } // // set new timeouts // if (!SetCommTimeouts(m_hCommPort, &m_timeoutsnew)) { dwLastError = GetLastError(); hr = HRESULT_FROM_WIN32(dwLastError); CHECK_HR(hr, "SetCommTimeouts() failed within SetPortState() when setting the new timeouts."); return hr; } return hr; }
HRESULT CMFCamCapture::init() { IMFMediaType *pType = NULL; HRESULT hr; CHECK_HR(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED)); CHECK_HR(hr = MFStartup(MF_VERSION)); // Configure the media type that the Sample Grabber will receive. // Setting the major and subtype is usually enough for the topology loader // to resolve the topology. CHECK_HR(hr = MFCreateMediaType(&pType)); CHECK_HR(hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)); CHECK_HR(hr = pType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB24)); // Create the sample grabber sink. CHECK_HR(hr = SampleGrabberCB::CreateInstance(&m_spSampleGrabber)); CHECK_HR(hr = MFCreateSampleGrabberSinkActivate(pType, m_spSampleGrabber, &m_spSinkActivate)); // To run as fast as possible, set this attribute (requires Windows 7): CHECK_HR(hr = m_spSinkActivate->SetUINT32(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, TRUE)); // Create the Media Session. CHECK_HR(hr = MFCreateMediaSession(NULL, &m_spSession)); CHECK_HR(hr = enumVideoDevices()); CHECK_HR(hr = setupVideoDevice()); CHECK_HR(hr = setupMfSession()); done: SafeRelease(&pType); return hr; }
/*----------------------------------------------------------------------------- FUNCTION: Connect( void ) PURPOSE: Setup Communication Port with our settings RETURN: S_OK and handle of com port if successful -----------------------------------------------------------------------------*/ HRESULT RS232Connection::Connect(_In_ LPCWSTR wszPortName, _Out_ HANDLE *phCommPort) { HRESULT hr = S_OK; DWORD dwLastError = 0; if (phCommPort == NULL) { hr = E_POINTER; CHECK_HR(hr, "A NULL phCommPort parameter was received"); return hr; } *phCommPort = NULL; // // retrieve a handle for the com port // and configure the port for asynchronous // communications. // m_hCommPort = CreateFileW(wszPortName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0); if (m_hCommPort == NULL) { dwLastError = GetLastError(); hr = HRESULT_FROM_WIN32(dwLastError); CHECK_HR(hr, "CreateFileW() failed in RS232Connection::Connect"); return hr; } // // Save original comm timeouts and set new ones // if (!GetCommTimeouts( m_hCommPort, &(m_timeoutsorig))) { dwLastError = GetLastError(); hr = HRESULT_FROM_WIN32(dwLastError); CHECK_HR(hr, "GetCommTimeouts() failed within RS232Connection::Connect"); return hr; } // // Set port state // hr = SetPortState(); if (FAILED(hr)) { CHECK_HR(hr, "SetPortState() failed within RS232Connection::Connect"); return hr; } // // set comm buffer sizes // if (!SetupComm(m_hCommPort, MAX_READ_BUFFER, MAX_WRITE_BUFFER)) { dwLastError = GetLastError(); hr = HRESULT_FROM_WIN32(dwLastError); CHECK_HR(hr, "SetupComm(SETDTR) failed within RS232Connection::Connect"); return hr; } // // raise DTR // if (!EscapeCommFunction(m_hCommPort, SETDTR)) { dwLastError = GetLastError(); hr = HRESULT_FROM_WIN32(dwLastError); CHECK_HR(hr, "EscapeCommFunction() failed within RS232Connection::Connect"); return hr; } // // set overall connect flag // m_fConnected = TRUE; // // set the return value // *phCommPort = m_hCommPort; if (SUCCEEDED(hr)) { TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FLAG_DEVICE, "%!FUNC! handle: %p", m_hCommPort); } return hr; }
HRESULT WpdBaseDriver::DispatchWpdMessage(_In_ IPortableDeviceValues* pParams, _In_ IPortableDeviceValues* pResults) { HRESULT hr = S_OK; GUID guidCommandCategory = {0}; DWORD dwCommandID = 0; PROPERTYKEY CommandKey = WPD_PROPERTY_NULL; if (hr == S_OK) { hr = pParams->GetGuidValue(WPD_PROPERTY_COMMON_COMMAND_CATEGORY, &guidCommandCategory); CHECK_HR(hr, "Failed to get WPD_PROPERTY_COMMON_COMMAND_CATEGORY from input parameters"); } if (hr == S_OK) { hr = pParams->GetUnsignedIntegerValue(WPD_PROPERTY_COMMON_COMMAND_ID, &dwCommandID); CHECK_HR(hr, "Failed to get WPD_PROPERTY_COMMON_COMMAND_ID from input parameters"); } // If WPD_PROPERTY_COMMON_COMMAND_CATEGORY or WPD_PROPERTY_COMMON_COMMAND_ID could not be extracted // properly then we should return E_INVALIDARG to the client. if (FAILED(hr)) { hr = E_INVALIDARG; CHECK_HR(hr, "Failed to get WPD_PROPERTY_COMMON_COMMAND_CATEGORY or WPD_PROPERTY_COMMON_COMMAND_ID from input parameters"); } if (hr == S_OK) { CommandKey.fmtid = guidCommandCategory; CommandKey.pid = dwCommandID; if (CommandKey.fmtid == WPD_CATEGORY_OBJECT_ENUMERATION) { hr = m_ObjectEnum.DispatchWpdMessage(CommandKey, pParams, pResults); } else if (CommandKey.fmtid == WPD_CATEGORY_OBJECT_PROPERTIES) { hr = m_ObjectProperties.DispatchWpdMessage(CommandKey, pParams, pResults); } else if (CommandKey.fmtid == WPD_CATEGORY_OBJECT_RESOURCES) { hr = m_ObjectResources.DispatchWpdMessage(CommandKey, pParams, pResults); } else if (CommandKey.fmtid == WPD_CATEGORY_CAPABILITIES) { hr = m_Capabilities.DispatchWpdMessage(CommandKey, pParams, pResults); } else if (IsEqualPropertyKey(CommandKey, WPD_COMMAND_COMMON_GET_OBJECT_IDS_FROM_PERSISTENT_UNIQUE_IDS)) { hr = OnGetObjectIDsFromPersistentUniqueIDs(pParams, pResults); } else { hr = E_NOTIMPL; CHECK_HR(hr, "Unknown command %ws.%d received",CComBSTR(CommandKey.fmtid), CommandKey.pid); } } HRESULT hrTemp = pResults->SetErrorValue(WPD_PROPERTY_COMMON_HRESULT, hr); CHECK_HR(hrTemp, ("Failed to set WPD_PROPERTY_COMMON_HRESULT")); // Set to a success code, to indicate that the message was received. // the return code for the actual command's results is stored in the // WPD_PROPERTY_COMMON_HRESULT property. hr = S_OK; return hr; }
/** * This method is called when we receive a WPD_COMMAND_COMMON_GET_OBJECT_IDS_FROM_PERSISTENT_UNIQUE_IDS * command. * * The parameters sent to us are: * - WPD_PROPERTY_COMMON_PERSISTENT_UNIQUE_IDS: Contains an IPortableDevicePropVariantCollection of VT_LPWSTR, * indicating the PersistentUniqueIDs. * * The driver should: * - Iterate through the PersistentUniqueIDs, and convert to a currently valid object id. * This object ID list should be returned as an IPortableDevicePropVariantCollection of VT_LPWSTR * in WPD_PROPERTY_COMMON_OBJECT_IDS. * Order is implicit, i.e. the first element in the Persistent Unique ID list corresponds to the * to the first element of the ObjectID list and so on. * * For those elements where an existing ObjectID could not be found (e.g. the * object is no longer present on the device), the element will contain the * empty string (L""). */ HRESULT WpdBaseDriver::OnGetObjectIDsFromPersistentUniqueIDs( _In_ IPortableDeviceValues* pParams, _In_ IPortableDeviceValues* pResults) { HRESULT hr = S_OK; DWORD dwCount = 0; CComPtr<IPortableDevicePropVariantCollection> pPersistentIDs; CComPtr<IPortableDevicePropVariantCollection> pObjectIDs; if((pParams == NULL) || (pResults == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } // Get the list of Persistent IDs if (hr == S_OK) { hr = pParams->GetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_COMMON_PERSISTENT_UNIQUE_IDS, &pPersistentIDs); CHECK_HR(hr, "Failed to get WPD_PROPERTY_COMMON_PERSISTENT_UNIQUE_IDS"); } // Create the collection to hold the ObjectIDs if (hr == S_OK) { hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDevicePropVariantCollection, (VOID**) &pObjectIDs); CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDevicePropVariantCollection"); } // Iterate through the persistent ID list and add the equivalent object ID for each element. if (hr == S_OK) { hr = pPersistentIDs->GetCount(&dwCount); CHECK_HR(hr, "Failed to get count from persistent ID collection"); if (hr == S_OK) { DWORD dwIndex = 0; PROPVARIANT pvPersistentID = {0}; PROPVARIANT pvObjectID = {0}; PropVariantInit(&pvPersistentID); PropVariantInit(&pvObjectID); for(dwIndex = 0; dwIndex < dwCount; dwIndex++) { pvObjectID.vt = VT_LPWSTR; hr = pPersistentIDs->GetAt(dwIndex, &pvPersistentID); CHECK_HR(hr, "Failed to get persistent ID at index %d", dwIndex); // Since our persistent unique identifier are identical to our object // identifiers, we just return it back to the caller. if (hr == S_OK) { pvObjectID.pwszVal = AtlAllocTaskWideString(pvPersistentID.pwszVal); } if (hr == S_OK) { hr = pObjectIDs->Add(&pvObjectID); CHECK_HR(hr, "Failed to add next Object ID"); } PropVariantClear(&pvPersistentID); PropVariantClear(&pvObjectID); if(FAILED(hr)) { break; } } } } if (hr == S_OK) { hr = pResults->SetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_COMMON_OBJECT_IDS, pObjectIDs); CHECK_HR(hr, "Failed to set WPD_PROPERTY_COMMON_OBJECT_IDS"); } return hr; }
/** * This method is called when we receive a WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_FORMAT_START * command. * * The parameters sent to us are: * - WPD_PROPERTY_OBJECT_PROPERTIES_BULK_OBJECT_FORMAT: Identifies the format of the objects the * client is interested in. * - WPD_PROPERTY_OBJECT_PROPERTIES_BULK_PARENT_OBJECT_ID: Identifies the parent object from which the * operation should start. * - WPD_PROPERTY_OBJECT_PROPERTIES_BULK_DEPTH: Indicates the hierarchical depth of the operation * from the parent object. * - WPD_PROPERTY_OBJECT_PROPERTIES_BULK_PROPERTY_KEYS: a collection of property keys, identifying which * specific property values we are requested to return. If this doesn't exist, then * ALL object proeprties should be returned for the specified objects. * * The driver should: * - Create a new context for this bulk property operation. * - Return an identifier for the context in WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT. */ HRESULT WpdObjectPropertiesBulk::OnGetValuesByObjectFormatStart( _In_ IPortableDeviceValues* pParams, _In_ IPortableDeviceValues* pResults) { HRESULT hr = S_OK; CComPtr<IPortableDeviceKeyCollection> pKeys; GUID guidObjectFormat = GUID_NULL; LPWSTR pszParentObjectID = NULL; DWORD dwDepth = 0; ContextMap* pContextMap = NULL; // Get the object format. hr = pParams->GetGuidValue(WPD_PROPERTY_OBJECT_PROPERTIES_BULK_OBJECT_FORMAT, &guidObjectFormat); CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_PROPERTIES_BULK_OBJECT_FORMAT"); // Get the parent object id. if (SUCCEEDED(hr)) { hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_PROPERTIES_BULK_PARENT_OBJECT_ID, &pszParentObjectID); CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_PROPERTIES_BULK_PARENT_OBJECT_ID"); } // Get the depth. if (SUCCEEDED(hr)) { hr = pParams->GetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_PROPERTIES_BULK_DEPTH, &dwDepth); CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_PROPERTIES_BULK_DEPTH"); } // Get the IPortableDeviceKeyCollection which contains the collection // keys of properties being read on the multiple objects. if (SUCCEEDED(hr)) { hr = pParams->GetIPortableDeviceKeyCollectionValue(WPD_PROPERTY_OBJECT_PROPERTIES_BULK_PROPERTY_KEYS, &pKeys); if (FAILED(hr)) { // Client is asking for all properties. pKeys = NULL; hr = S_OK; } } // Get the context map which the driver stored in pParams for convenience if (SUCCEEDED(hr)) { hr = pParams->GetIUnknownValue(PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP, (IUnknown**)&pContextMap); CHECK_HR(hr, "Failed to get PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP"); } if (SUCCEEDED(hr)) { LPWSTR pwszContext = NULL; ACCESS_SCOPE Scope = m_pDevice->GetAccessScope(pParams); hr = CreateBulkPropertiesContext(Scope, pContextMap, guidObjectFormat, pszParentObjectID, dwDepth, pKeys, &pwszContext); if (SUCCEEDED(hr)) { hr = pResults->SetStringValue(WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT, pwszContext); CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT"); } // Free the memory. CoTaskMemFree ignores NULLs so no need to check. CoTaskMemFree(pwszContext); } // Free the memory. CoTaskMemFree ignores NULLs so no need to check. CoTaskMemFree(pszParentObjectID); SAFE_RELEASE(pContextMap); return hr; }
HRESULT WpdObjectPropertiesBulk::CreateBulkPropertiesContext( __in ACCESS_SCOPE Scope, __inout ContextMap* pContextMap, __in REFGUID guidObjectFormat, __in LPCWSTR pszParentObjectID, __in DWORD dwDepth, __in IPortableDeviceKeyCollection* pProperties, __deref_out_opt LPWSTR* ppszBulkPropertiesContext) { HRESULT hr = S_OK; BulkPropertiesContext* pContext = NULL; CAtlStringW strKey; CComPtr<IPortableDevicePropVariantCollection> pObjectIDs; if((pContextMap == NULL) || (pszParentObjectID == NULL) || (ppszBulkPropertiesContext == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } *ppszBulkPropertiesContext = NULL; hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDevicePropVariantCollection, (VOID**) &pObjectIDs); CHECK_HR(hr, "Failed to CoCreate CLSID_IPortableDevicePropVariantCollection"); if (hr == S_OK) { hr = m_pDevice->GetObjectIDsByFormat(Scope, guidObjectFormat, pszParentObjectID, dwDepth, pObjectIDs); CHECK_HR(hr, "Faield to get list of object ids by format"); } if (hr == S_OK) { pContext = new BulkPropertiesContext(); if(pContext == NULL) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate new bulk properties context"); } } if (hr == S_OK) { pContext->Properties = pProperties; pContext->ObjectIDs = pObjectIDs; pContext->Scope = Scope; hr = pContextMap->Add(pContext, strKey); CHECK_HR(hr, "Failed to insert bulk property operation context into our context Map"); } if (hr == S_OK) { *ppszBulkPropertiesContext = AtlAllocTaskWideString(strKey); if (*ppszBulkPropertiesContext == NULL) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate bulk properties context"); } } SAFE_RELEASE(pContext); return hr; }
/** * This method is called when we receive a WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_FORMAT_NEXT * command. * * The parameters sent to us are: * - WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT: the context the driver returned to * the client in OnGetValuesByObjectFormatStart. * * The driver should: * - Return the next set of property values in WPD_PROPERTY_OBJECT_PROPERTIES_BULK_VALUES. * If there are no more properties to be read an * empty collection should be returned. * - It is up to the driver to return as many object property values as it wants. If zero values are returned * it is assumed the bulk operation is complete and the WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_FORMAT_END * will be called next. * * - S_OK should be returned if the collection can be returned successfully. * - Any error return indicates that the driver did not fill in any results, and the caller will * not attempt to unpack any property values. */ HRESULT WpdObjectPropertiesBulk::OnGetValuesByObjectFormatNext( _In_ IPortableDeviceValues* pParams, _In_ IPortableDeviceValues* pResults) { HRESULT hr = S_OK; LPWSTR pwszContext = NULL; BulkPropertiesContext* pContext = NULL; DWORD cObjects = 0; CComPtr<IPortableDeviceValuesCollection> pCollection; hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT, &pwszContext); CHECK_HR(hr, "Failed to get WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT from IPortableDeviceValues"); // Get the bulk property operation context if (SUCCEEDED(hr)) { hr = GetClientContext(pParams, pwszContext, (IUnknown**) &pContext); CHECK_HR(hr, "Failed to get bulk property context"); } // Make sure the the collection holds VT_LPWSTR values. if (SUCCEEDED(hr)) { hr = pContext->ObjectIDs->ChangeType(VT_LPWSTR); CHECK_HR(hr, "Failed to change objectIDs collection to VT_LPWSTR"); } if (SUCCEEDED(hr)) { hr = pContext->ObjectIDs->GetCount(&cObjects); CHECK_HR(hr, "Failed to get number of objectIDs from bulk properties context"); } if (SUCCEEDED(hr)) { cObjects = cObjects - pContext->NextObject; if(cObjects > MAX_OBJECTS_TO_RETURN) { cObjects = MAX_OBJECTS_TO_RETURN; } } if (SUCCEEDED(hr)) { hr = CoCreateInstance(CLSID_PortableDeviceValuesCollection, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValuesCollection, (VOID**) &pCollection); CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValuesCollection"); } if (SUCCEEDED(hr)) { for (DWORD dwIndex = pContext->NextObject, dwCount = 0; dwCount < cObjects; dwCount++, dwIndex++) { CComPtr<IPortableDeviceValues> pValues; PROPVARIANT pv = {0}; PropVariantInit(&pv); hr = pContext->ObjectIDs->GetAt(dwIndex, &pv); CHECK_HR(hr, "Failed to get next object ID from bulk properties context"); if (SUCCEEDED(hr)) { hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**) &pValues); CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValuesCollection"); } if (SUCCEEDED(hr)) { // If a key list was supplied, get the specified object properties, other get all // properties. if(pContext->Properties != NULL) { hr = m_pDevice->GetPropertyValues(pContext->Scope, pv.pwszVal, pContext->Properties, pValues); CHECK_HR(hr, "Failed to get property values for [%ws]", pv.pwszVal); } else { hr = m_pDevice->GetAllPropertyValues(pContext->Scope,pv.pwszVal, pValues); CHECK_HR(hr, "Failed to get property values for [%ws]", pv.pwszVal); } } // Add the ObjectID to the returned results if (SUCCEEDED(hr)) { hr = pValues->SetStringValue(WPD_OBJECT_ID, pv.pwszVal); CHECK_HR(hr, "Failed to set WPD_OBJECT_ID for %ws", pv.pwszVal); } if (SUCCEEDED(hr)) { hr = pCollection->Add(pValues); CHECK_HR(hr, "Failed to add IPortableDeviceValues to IPortableDeviceValuesCollection"); } PropVariantClear(&pv); pContext->NextObject++; } } if (SUCCEEDED(hr)) { hr = pResults->SetIUnknownValue(WPD_PROPERTY_OBJECT_PROPERTIES_BULK_VALUES, pCollection); CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_PROPERTIES_BULK_VALUES"); } // Free the memory. CoTaskMemFree ignores NULLs so no need to check. CoTaskMemFree(pwszContext); SAFE_RELEASE(pContext); return hr; }
HRESULT Scheduler::StartScheduler(IMFClock *pClock) { if (m_hSchedulerThread != NULL) { return E_UNEXPECTED; } HRESULT hr = S_OK; DWORD dwID = 0; CopyComPointer(m_pClock, pClock); // Set a high the timer resolution (ie, short timer period). timeBeginPeriod(1); // Create an event to wait for the thread to start. m_hThreadReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (m_hThreadReadyEvent == NULL) { CHECK_HR(hr = HRESULT_FROM_WIN32(GetLastError())); } // Create an event to wait for flush commands to complete. m_hFlushEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (m_hFlushEvent == NULL) { CHECK_HR(hr = HRESULT_FROM_WIN32(GetLastError())); } // Create the scheduler thread. m_hSchedulerThread = CreateThread(NULL, 0, SchedulerThreadProc, (LPVOID)this, 0, &dwID); if (m_hSchedulerThread == NULL) { CHECK_HR(hr = HRESULT_FROM_WIN32(GetLastError())); } HANDLE hObjects[] = { m_hThreadReadyEvent, m_hSchedulerThread }; DWORD dwWait = 0; // Wait for the thread to signal the "thread ready" event. dwWait = WaitForMultipleObjects(2, hObjects, FALSE, INFINITE); // Wait for EITHER of these handles. if (WAIT_OBJECT_0 != dwWait) { // The thread terminated early for some reason. This is an error condition. CloseHandle(m_hSchedulerThread); m_hSchedulerThread = NULL; CHECK_HR(hr = E_UNEXPECTED); } m_dwThreadID = dwID; done: // Regardless success/failure, we are done using the "thread ready" event. if (m_hThreadReadyEvent) { CloseHandle(m_hThreadReadyEvent); m_hThreadReadyEvent = NULL; } return hr; }
HRESULT WpdServiceMethods::StartMethod( _In_ IPortableDeviceValues* pParams, _Outptr_ LPWSTR* ppwszMethodContext) { HRESULT hr = S_OK; ContextMap* pContextMap = NULL; ServiceMethodContext* pContext = NULL; GUID Method = GUID_NULL; CAtlStringW strKey; CComPtr<IPortableDeviceValues> pMethodParams; if((pParams == NULL) || (ppwszMethodContext == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } *ppwszMethodContext = NULL; // Check if the method is supported hr = pParams->GetGuidValue(WPD_PROPERTY_SERVICE_METHOD, &Method); CHECK_HR(hr, "Failed to get WPD_PROPERTY_SERVICE_METHOD"); if (SUCCEEDED(hr) && !m_pGattService->IsMethodSupported(Method)) { hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); CHECK_HR(hr, "Unknown method %ws received",CComBSTR(Method)); } if (SUCCEEDED(hr)) { // Get the context map which the driver stored in pParams for convenience hr = pParams->GetIUnknownValue(PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP, (IUnknown**)&pContextMap); CHECK_HR(hr, "Failed to get PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP"); } if (SUCCEEDED(hr)) { pContext = new ServiceMethodContext(); if(pContext == NULL) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate new method context"); } } if (SUCCEEDED(hr)) { hr = pContextMap->Add(pContext, strKey); CHECK_HR(hr, "Failed to insert method context into our context Map"); } if (SUCCEEDED(hr)) { hr = pContext->Initialize(this, pParams, strKey); CHECK_HR(hr, "Failed to initialize the method context"); } if (SUCCEEDED(hr)) { *ppwszMethodContext = AtlAllocTaskWideString(strKey); if (*ppwszMethodContext == NULL) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate method context string"); } } SAFE_RELEASE(pContextMap); SAFE_RELEASE(pContext); return hr; }
HRESULT WpdObjectProperties::DispatchWpdMessage(const PROPERTYKEY& Command, IPortableDeviceValues* pParams, IPortableDeviceValues* pResults) { HRESULT hr = S_OK; if (hr == S_OK) { if (Command.fmtid != WPD_CATEGORY_OBJECT_PROPERTIES) { hr = E_INVALIDARG; CHECK_HR(hr, "This object does not support this command category %ws",CComBSTR(Command.fmtid)); } } if (hr == S_OK) { if (IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_GET_SUPPORTED)) { hr = OnGetSupportedProperties(pParams, pResults); CHECK_HR(hr, "Failed to get supported properties"); } else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_GET)) { hr = OnGetValues(pParams, pResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to read properties"); } } else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_GET_ALL)) { hr = OnGetAllValues(pParams, pResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to read all properties"); } } else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_SET)) { hr = OnWriteProperties(pParams, pResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to write properties"); } } else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_GET_ATTRIBUTES)) { hr = OnGetAttributes(pParams, pResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to get property attributes"); } } else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_DELETE)) { hr = OnDelete(pParams, pResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to delete properties"); } } else { hr = E_NOTIMPL; CHECK_HR(hr, "This object does not support this command id %d", Command.pid); } } return hr; }
/** * This method is called when we receive a WPD_COMMAND_OBJECT_RESOURCES_OPEN * command. * * The parameters sent to us are: * - WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID: the object identifier of the * object which contains the specified resource * * - WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS: the specified resource * to open * * - WPD_PROPERTY_OBJECT_RESOURCES_ACCESS_MODE: the access mode to which to * open the specified resource * * The driver should: * - Create a new context for this resource operation. * - Return an identifier for the context in WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT. * - Set the optimal transfer size in WPD_PROPERTY_OBJECT_RESOURCES_OPTIMAL_TRANSFER_BUFFER_SIZE * */ HRESULT WpdObjectResources::OnOpenResource( _In_ IPortableDeviceValues* pParams, _In_ IPortableDeviceValues* pResults) { HRESULT hr = S_OK; LPWSTR wszObjectID = NULL; PROPERTYKEY Key = WPD_PROPERTY_NULL; DWORD dwMode = STGM_READ; CAtlStringW strStrObjectID; CAtlStringW strResourceContext; ContextMap* pContextMap = NULL; // Get the Object identifier of the object which contains the specified resource hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID, &wszObjectID); if (hr != S_OK) { hr = E_INVALIDARG; CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID"); } // Get the resource key if (hr == S_OK) { hr = pParams->GetKeyValue(WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS, &Key); CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS"); } // Get the access mode if (hr == S_OK) { hr = pParams->GetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_ACCESS_MODE, &dwMode); CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_ACCESS_MODE"); } // Validate whether the params given to us are correct. In this case, we need to check that the object // supports the resource requested, and can be opened in the requested access mode. if (hr == S_OK) { // In this sample, we only have one object (README_FILE_OBJECT_ID) which supports a // resource (WPD_RESOURCE_DEFAULT) for reading only. // So if any other Object ID or any other resource is specified, it must be invalid. strStrObjectID = wszObjectID; if(strStrObjectID.CompareNoCase(README_FILE_OBJECT_ID) != 0) { hr = E_INVALIDARG; CHECK_HR(hr, "Object [%ws] does not support resources", wszObjectID); } if (hr == S_OK) { if (!IsEqualPropertyKey(Key, WPD_RESOURCE_DEFAULT)) { hr = E_INVALIDARG; CHECK_HR(hr, "Only WPD_RESOURCE_DEFAULT is supported in this sample driver"); } } if (hr == S_OK) { if ((dwMode & STGM_WRITE) != 0) { hr = E_ACCESSDENIED; CHECK_HR(hr, "This resource is not available for write access"); } } } // Get the context map which the driver stored in pParams for convenience if (hr == S_OK) { hr = pParams->GetIUnknownValue(PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP, (IUnknown**)&pContextMap); CHECK_HR(hr, "Failed to get PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP"); } // Create a new resource operation context, initialize it, and add it to the client context map. if (hr == S_OK) { WpdObjectResourceContext* pResourceContext = new WpdObjectResourceContext(); if (pResourceContext != NULL) { // Initialize the resource context with ... pResourceContext->m_strObjectID = wszObjectID; pResourceContext->m_Resource = Key; pResourceContext->m_BytesTransferred = 0; pResourceContext->m_BytesTotal = GetObjectSize(wszObjectID); // Add the resource context to the context map pContextMap->Add(pResourceContext, strResourceContext); } else { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate resource context"); } SAFE_RELEASE(pResourceContext); } if (hr == S_OK) { hr = pResults->SetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT, strResourceContext); CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT"); } // Set the optimal buffer size if (hr == S_OK) { hr = pResults->SetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_OPTIMAL_TRANSFER_BUFFER_SIZE, FILE_OPTIMAL_READ_BUFFER_SIZE_VALUE); CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_OPTIMAL_TRANSFER_BUFFER_SIZE value"); } // Free the memory. CoTaskMemFree ignores NULLs so no need to check. CoTaskMemFree(wszObjectID); SAFE_RELEASE(pContextMap); return hr; }
/** * This method is called when we receive a WPD_COMMAND_OBJECT_PROPERTIES_SET * command. * * The parameters sent to us are: * - WPD_PROPERTY_OBJECT_PROPERTIES_OBJECT_ID: identifies the object whose property values we want to return. * - WPD_PROPERTY_OBJECT_PROPERTIES_PROPERTY_VALUES: an IPortableDeviceValues of values, identifying which * specific property values we are requested to write. * * The driver should: * - Write all requested property values. For each property, a write result should be returned in the * write result property store. * - If any property write failed, the corresponding write result value should be * set to type VT_ERROR with the 'scode' member holding the HRESULT reason for the failure. * - S_OK should be returned if all properties were written successfully. * - S_FALSE should be returned if any property write failed. * - Any error return indicates that the driver did not write any results, and the caller will * not attempt to unpack any property write results. */ HRESULT WpdObjectProperties::OnWriteProperties( IPortableDeviceValues* pParams, IPortableDeviceValues* pResults) { HRESULT hr = S_OK; LPWSTR pszObjectID = NULL; CComPtr<IPortableDeviceValues> pValues; CComPtr<IPortableDeviceValues> pWriteResults; CComPtr<IPortableDeviceValues> pEventParams; if (hr == S_OK) { hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_PROPERTIES_OBJECT_ID, &pszObjectID); CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_PROPERTIES_OBJECT_ID"); } if (hr == S_OK) { hr = pParams->GetIPortableDeviceValuesValue(WPD_PROPERTY_OBJECT_PROPERTIES_PROPERTY_VALUES, &pValues); CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_PROPERTIES_PROPERTY_VALUES"); } if (hr == S_OK) { hr = m_pFakeDevice->WritePropertiesOnObject(pszObjectID, pValues, &pWriteResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to write properties on [%ws]", pszObjectID); } } // Be sure to preserve possible S_FALSE returns if (SUCCEEDED(hr)) { HRESULT hrTemp = S_OK; hrTemp = pResults->SetIPortableDeviceValuesValue(WPD_PROPERTY_OBJECT_PROPERTIES_PROPERTY_WRITE_RESULTS, pWriteResults); CHECK_HR(hrTemp, ("Failed to set WPD_PROPERTY_OBJECT_PROPERTIES_PROPERTY_WRITE_RESULTS")); if(FAILED(hrTemp)) { hr = hrTemp; } pEventParams = NULL; hrTemp = m_pFakeDevice->GetObjectPropertiesForEvent(pszObjectID, &pEventParams); CHECK_HR(hrTemp, "Failed to get properties for event on object %ws", pszObjectID); if (hrTemp == S_OK) { HRESULT hrEvent = S_OK; // Set the event-specific parameters hrEvent = pEventParams->SetGuidValue(WPD_EVENT_PARAMETER_EVENT_ID, WPD_EVENT_OBJECT_UPDATED); CHECK_HR(hrEvent, "Failed to add WPD_EVENT_PARAMETER_EVENT_ID"); // Send the Event if (hrEvent == S_OK) { PostWpdEvent(pParams, pEventParams); } } } // Free the memory. CoTaskMemFree ignores NULLs so no need to check. CoTaskMemFree(pszObjectID); return hr; }
/** * This method is called to populate resource attributes found on a particular object * resource. * * The parameters sent to us are: * wszObjectID - the object whose resource attributes are being requested * Key - the resource on the specified object whose attributes are being returned * pAttributes - An IPortableDeviceValues to be populated with resource attributes. * * The driver should: * Add attributes pertaining to the resource on the specified object. */ HRESULT WpdObjectResources::GetResourceAttributesForObject( _In_ LPCWSTR wszObjectID, _In_ REFPROPERTYKEY Key, _In_ IPortableDeviceValues* pAttributes) { HRESULT hr = S_OK; CAtlStringW strObjectID; if ((wszObjectID == NULL) || (pAttributes == NULL)) { hr = E_INVALIDARG; return hr; } strObjectID = wszObjectID; if ((strObjectID.CompareNoCase(README_FILE_OBJECT_ID) == 0) && (IsEqualPropertyKey(Key, WPD_RESOURCE_DEFAULT))) { if (hr == S_OK) { hr = pAttributes->SetBoolValue(WPD_RESOURCE_ATTRIBUTE_CAN_DELETE, FALSE); CHECK_HR(hr, "Failed to set WPD_RESOURCE_ATTRIBUTE_CAN_DELETE"); } if (hr == S_OK) { hr = pAttributes->SetUnsignedLargeIntegerValue(WPD_RESOURCE_ATTRIBUTE_TOTAL_SIZE, GetObjectSize(strObjectID)); CHECK_HR(hr, "Failed to set WPD_RESOURCE_ATTRIBUTE_TOTAL_SIZE"); } if (hr == S_OK) { hr = pAttributes->SetBoolValue(WPD_RESOURCE_ATTRIBUTE_CAN_READ, TRUE); CHECK_HR(hr, "Failed to set WPD_RESOURCE_ATTRIBUTE_CAN_READ"); } if (hr == S_OK) { hr = pAttributes->SetBoolValue(WPD_RESOURCE_ATTRIBUTE_CAN_WRITE, FALSE); CHECK_HR(hr, "Failed to set WPD_RESOURCE_ATTRIBUTE_CAN_WRITE"); } if (hr == S_OK) { hr = pAttributes->SetBoolValue(WPD_RESOURCE_ATTRIBUTE_CAN_DELETE, FALSE); CHECK_HR(hr, "Failed to set WPD_RESOURCE_ATTRIBUTE_CAN_DELETE"); } if (hr == S_OK) { hr = pAttributes->SetGuidValue(WPD_RESOURCE_ATTRIBUTE_FORMAT, GetObjectFormat(strObjectID)); CHECK_HR(hr, "Failed to set WPD_RESOURCE_ATTRIBUTE_FORMAT"); } if (hr == S_OK) { hr = pAttributes->SetUnsignedIntegerValue(WPD_RESOURCE_ATTRIBUTE_OPTIMAL_READ_BUFFER_SIZE, FILE_OPTIMAL_READ_BUFFER_SIZE_VALUE); CHECK_HR(hr, "Failed to set WPD_RESOURCE_ATTRIBUTE_OPTIMAL_READ_BUFFER_SIZE"); } if (hr == S_OK) { hr = pAttributes->SetUnsignedIntegerValue(WPD_RESOURCE_ATTRIBUTE_OPTIMAL_WRITE_BUFFER_SIZE, FILE_OPTIMAL_WRITE_BUFFER_SIZE_VALUE); CHECK_HR(hr, "Failed to set WPD_RESOURCE_ATTRIBUTE_OPTIMAL_WRITE_BUFFER_SIZE"); } } return hr; }
HRESULT CLAVOutputPin::DeliverPacket(Packet *pPacket) { HRESULT hr = S_OK; IMediaSample *pSample = nullptr; long nBytes = (long)pPacket->GetDataSize(); if(nBytes == 0) { goto done; } CHECK_HR(hr = GetDeliveryBuffer(&pSample, nullptr, nullptr, 0)); if (m_bPacketAllocator) { ILAVMediaSample *pLAVSample = nullptr; CHECK_HR(hr = pSample->QueryInterface(&pLAVSample)); CHECK_HR(hr = pLAVSample->SetPacket(pPacket)); SafeRelease(&pLAVSample); } else { // Resize buffer if it is too small // This can cause a playback hick-up, we should avoid this if possible by setting a big enough buffer size if(nBytes > pSample->GetSize()) { SafeRelease(&pSample); ALLOCATOR_PROPERTIES props, actual; CHECK_HR(hr = m_pAllocator->GetProperties(&props)); // Give us 2 times the requested size, so we don't resize every time props.cbBuffer = nBytes*2; if(props.cBuffers > 1) { CHECK_HR(hr = __super::DeliverBeginFlush()); CHECK_HR(hr = __super::DeliverEndFlush()); } CHECK_HR(hr = m_pAllocator->Decommit()); CHECK_HR(hr = m_pAllocator->SetProperties(&props, &actual)); CHECK_HR(hr = m_pAllocator->Commit()); CHECK_HR(hr = GetDeliveryBuffer(&pSample, nullptr, nullptr, 0)); } // Fill the sample BYTE* pData = nullptr; if(FAILED(hr = pSample->GetPointer(&pData)) || !pData) goto done; memcpy(pData, pPacket->GetData(), nBytes); } if(pPacket->pmt) { DbgLog((LOG_TRACE, 10, L"::DeliverPacket() - sending new media type to decoder")); pSample->SetMediaType(pPacket->pmt); pPacket->bDiscontinuity = true; CAutoLock cAutoLock(m_pLock); CMediaType pmt = *(pPacket->pmt); m_mts.clear(); m_mts.push_back(pmt); pPacket->pmt = nullptr; SetMediaType(&pmt); } bool fTimeValid = pPacket->rtStart != Packet::INVALID_TIME; // IBitRateInfo m_BitRate.nBytesSinceLastDeliverTime += nBytes; if (fTimeValid) { if (m_BitRate.rtLastDeliverTime == Packet::INVALID_TIME) { m_BitRate.rtLastDeliverTime = pPacket->rtStart; m_BitRate.nBytesSinceLastDeliverTime = 0; } if (m_BitRate.rtLastDeliverTime + 10000000 < pPacket->rtStart) { REFERENCE_TIME rtDiff = pPacket->rtStart - m_BitRate.rtLastDeliverTime; double dSecs, dBits; dSecs = rtDiff / 10000000.0; dBits = 8.0 * m_BitRate.nBytesSinceLastDeliverTime; m_BitRate.nCurrentBitRate = (DWORD)(dBits / dSecs); m_BitRate.rtTotalTimeDelivered += rtDiff; m_BitRate.nTotalBytesDelivered += m_BitRate.nBytesSinceLastDeliverTime; dSecs = m_BitRate.rtTotalTimeDelivered / 10000000.0; dBits = 8.0 * m_BitRate.nTotalBytesDelivered; m_BitRate.nAverageBitRate = (DWORD)(dBits / dSecs); m_BitRate.rtLastDeliverTime = pPacket->rtStart; m_BitRate.nBytesSinceLastDeliverTime = 0; } } CHECK_HR(hr = pSample->SetActualDataLength(nBytes)); CHECK_HR(hr = pSample->SetTime(fTimeValid ? &pPacket->rtStart : nullptr, fTimeValid ? &pPacket->rtStop : nullptr)); CHECK_HR(hr = pSample->SetMediaTime(nullptr, nullptr)); CHECK_HR(hr = pSample->SetDiscontinuity(pPacket->bDiscontinuity)); CHECK_HR(hr = pSample->SetSyncPoint(pPacket->bSyncPoint)); CHECK_HR(hr = pSample->SetPreroll(fTimeValid && pPacket->rtStart < 0)); // Deliver CHECK_HR(hr = Deliver(pSample)); done: if (!m_bPacketAllocator || !pSample) SAFE_DELETE(pPacket); SafeRelease(&pSample); return hr; }
void StartXAudio2() { IXAudio2MasteringVoice* pMasterVoice = nullptr; CoInitializeEx(NULL, COINIT_MULTITHREADED); CHECK_HR(XAudio2Create(&gpXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR)); CHECK_HR(gpXAudio2->CreateMasteringVoice(&pMasterVoice)); }
HRESULT CLAVOutputPin::DeliverPacket(Packet *pPacket) { HRESULT hr = S_OK; IMediaSample *pSample = NULL; long nBytes = (long)pPacket->GetDataSize(); if(nBytes == 0) { goto done; } CHECK_HR(hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0)); if (m_bPacketAllocator) { ILAVMediaSample *pLAVSample = NULL; CHECK_HR(hr = pSample->QueryInterface(&pLAVSample)); CHECK_HR(hr = pLAVSample->SetPacket(pPacket)); SafeRelease(&pLAVSample); } else { // Resize buffer if it is too small // This can cause a playback hick-up, we should avoid this if possible by setting a big enough buffer size if(nBytes > pSample->GetSize()) { SafeRelease(&pSample); ALLOCATOR_PROPERTIES props, actual; CHECK_HR(hr = m_pAllocator->GetProperties(&props)); // Give us 2 times the requested size, so we don't resize every time props.cbBuffer = nBytes*2; if(props.cBuffers > 1) { CHECK_HR(hr = __super::DeliverBeginFlush()); CHECK_HR(hr = __super::DeliverEndFlush()); } CHECK_HR(hr = m_pAllocator->Decommit()); CHECK_HR(hr = m_pAllocator->SetProperties(&props, &actual)); CHECK_HR(hr = m_pAllocator->Commit()); CHECK_HR(hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0)); } // Fill the sample BYTE* pData = NULL; if(FAILED(hr = pSample->GetPointer(&pData)) || !pData) goto done; memcpy(pData, pPacket->GetData(), nBytes); } if(pPacket->pmt) { DbgLog((LOG_TRACE, 10, L"::DeliverPacket() - sending new media type to decoder")); pSample->SetMediaType(pPacket->pmt); pPacket->bDiscontinuity = true; CAutoLock cAutoLock(m_pLock); CMediaType pmt = *(pPacket->pmt); m_mts.clear(); m_mts.push_back(pmt); pPacket->pmt = NULL; SetMediaType(&pmt); } bool fTimeValid = pPacket->rtStart != Packet::INVALID_TIME; CHECK_HR(hr = pSample->SetActualDataLength(nBytes)); CHECK_HR(hr = pSample->SetTime(fTimeValid ? &pPacket->rtStart : NULL, fTimeValid ? &pPacket->rtStop : NULL)); CHECK_HR(hr = pSample->SetMediaTime(NULL, NULL)); CHECK_HR(hr = pSample->SetDiscontinuity(pPacket->bDiscontinuity)); CHECK_HR(hr = pSample->SetSyncPoint(pPacket->bSyncPoint)); CHECK_HR(hr = pSample->SetPreroll(fTimeValid && pPacket->rtStart < 0)); // Deliver CHECK_HR(hr = Deliver(pSample)); done: if (!m_bPacketAllocator) SAFE_DELETE(pPacket); SafeRelease(&pSample); return hr; }
// Creates video samples based on a specified media type. HRESULT D3DPresentEngine::CreateVideoSamples(IMFMediaType *pFormat, VideoSampleList& videoSampleQueue) { if (pFormat == NULL) { return MF_E_UNEXPECTED; } HRESULT hr = S_OK; D3DFORMAT d3dFormat = D3DFMT_UNKNOWN; IMFSample *pVideoSample = NULL; AutoLock lock(m_ObjectLock); ReleaseResources(); // Helper object for reading the proposed type. VideoType videoType(pFormat); // Get some information about the video format. hr = videoType.GetFrameDimensions(&m_Width, &m_Height); CHECK_HR(hr, "D3DPresentEngine::CreateVideoSamples VideoType::GetFrameDimensions() failed"); hr = GetAspectRatio(pFormat, m_ArX, m_ArY); if (FAILED(hr)) { m_ArX = m_Width; m_ArY = m_Height; } //hr = videoType.GetFourCC((DWORD*)&d3dFormat); //CHECK_HR(hr, "D3DPresentEngine::CreateVideoSamples VideoType::GetFourCC() failed"); // Morpheus_xx, 2016-08-14: we force a format without alpha channel here, because rendering subtitles with MPC-HC engine expects this format. Actually I can't imagine a video format // that actually delivers alpha channel information. d3dFormat = D3DFMT_X8R8G8B8; for (int i = 0; i < NUM_PRESENTER_BUFFERS; i++) { CComPtr<IDirect3DTexture9> texture; hr = m_pDevice->CreateTexture(m_Width, m_Height, 1, D3DUSAGE_RENDERTARGET, d3dFormat, D3DPOOL_DEFAULT, &texture, NULL); if (FAILED(hr)) { Log("D3DPresentEngine::CreateVideoSamples Could not create texture %d. Error 0x%x", i, hr); break; } CComPtr<IDirect3DSurface9> surface; hr = texture->GetSurfaceLevel(0, &surface); if (FAILED(hr)) { Log("D3DPresentEngine::CreateVideoSamples Could not get surface from texture. Error 0x%x", hr); break; } hr = MFCreateVideoSampleFromSurface(surface, &pVideoSample); if (FAILED(hr)) { Log("D3DPresentEngine::CreateVideoSamples CreateVideoSampleFromSurface failed: 0x%x", hr); break; } // Add it to the list. hr = videoSampleQueue.InsertBack(pVideoSample); if (FAILED(hr)) { SAFE_RELEASE(pVideoSample); ReleaseResources(); return hr; } SAFE_RELEASE(pVideoSample); } return hr; }
HRESULT WpdObjectPropertiesBulk::DispatchWpdMessage( _In_ REFPROPERTYKEY Command, _In_ IPortableDeviceValues* pParams, _In_ IPortableDeviceValues* pResults) { HRESULT hr = S_OK; if (Command.fmtid != WPD_CATEGORY_OBJECT_PROPERTIES_BULK) { hr = E_INVALIDARG; CHECK_HR(hr, "This object does not support this command category %ws",CComBSTR(Command.fmtid)); } if (hr == S_OK) { if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_LIST_START)) { hr = OnGetValuesByObjectListStart(pParams, pResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to start bulk property operation"); } } else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_LIST_NEXT)) { hr = OnGetValuesByObjectListNext(pParams, pResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to do next bulk property operation"); } } else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_LIST_END)) { hr = OnGetValuesByObjectListEnd(pParams, pResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to end bulk property operation"); } } else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_FORMAT_START)) { hr = OnGetValuesByObjectFormatStart(pParams, pResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to start bulk property operation"); } } else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_FORMAT_NEXT)) { hr = OnGetValuesByObjectFormatNext(pParams, pResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to do next bulk property operation"); } } else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_FORMAT_END)) { hr = OnGetValuesByObjectFormatEnd(pParams, pResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to end bulk property operation "); } } else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_BULK_SET_VALUES_BY_OBJECT_LIST_START)) { hr = OnSetValuesByObjectListStart(pParams, pResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to set bulk property operation"); } } else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_BULK_SET_VALUES_BY_OBJECT_LIST_NEXT)) { hr = OnSetValuesByObjectListNext(pParams, pResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to set bulk property operation"); } } else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_PROPERTIES_BULK_SET_VALUES_BY_OBJECT_LIST_END)) { hr = OnSetValuesByObjectListEnd(pParams, pResults); if(FAILED(hr)) { CHECK_HR(hr, "Failed to set bulk property operation"); } } else { hr = E_NOTIMPL; CHECK_HR(hr, "This object does not support this command id %d", Command.pid); } } return hr; }
HRESULT FakeContactsServiceContent::GetValue( REFPROPERTYKEY Key, __out IPortableDeviceValues* pStore) { HRESULT hr = S_OK; PropVariantWrapper pvValue; if (IsEqualPropertyKey(Key, WPD_OBJECT_ID)) { // Add WPD_OBJECT_ID pvValue = ObjectID; hr = pStore->SetValue(WPD_OBJECT_ID, &pvValue); CHECK_HR(hr, ("Failed to set WPD_OBJECT_ID")); } else if (IsEqualPropertyKey(Key, WPD_OBJECT_NAME)) { // Add WPD_OBJECT_NAME pvValue = Name; hr = pStore->SetValue(WPD_OBJECT_NAME, &pvValue); CHECK_HR(hr, ("Failed to set WPD_OBJECT_NAME")); } else if (IsEqualPropertyKey(Key, WPD_OBJECT_PERSISTENT_UNIQUE_ID)) { // Add WPD_OBJECT_PERSISTENT_UNIQUE_ID pvValue = PersistentUniqueID; hr = pStore->SetValue(WPD_OBJECT_PERSISTENT_UNIQUE_ID, &pvValue); CHECK_HR(hr, ("Failed to set WPD_OBJECT_PERSISTENT_UNIQUE_ID")); } else if (IsEqualPropertyKey(Key, WPD_OBJECT_PARENT_ID)) { // Add WPD_OBJECT_PARENT_ID pvValue = ParentID; hr = pStore->SetValue(WPD_OBJECT_PARENT_ID, &pvValue); CHECK_HR(hr, ("Failed to set WPD_OBJECT_PARENT_ID")); } else if (IsEqualPropertyKey(Key, WPD_OBJECT_FORMAT)) { // Add WPD_OBJECT_FORMAT hr = pStore->SetGuidValue(WPD_OBJECT_FORMAT, Format); CHECK_HR(hr, ("Failed to set WPD_OBJECT_FORMAT")); } else if (IsEqualPropertyKey(Key, WPD_OBJECT_CONTENT_TYPE)) { // Add WPD_OBJECT_CONTENT_TYPE hr = pStore->SetGuidValue(WPD_OBJECT_CONTENT_TYPE, ContentType); CHECK_HR(hr, ("Failed to set WPD_OBJECT_CONTENT_TYPE")); } else if (IsEqualPropertyKey(Key, WPD_OBJECT_CAN_DELETE)) { // Add WPD_OBJECT_CAN_DELETE hr = pStore->SetBoolValue(WPD_OBJECT_CAN_DELETE, CanDelete); CHECK_HR(hr, ("Failed to set WPD_OBJECT_CAN_DELETE")); } else if (IsEqualPropertyKey(Key, WPD_FUNCTIONAL_OBJECT_CATEGORY)) { // Add WPD_FUNCTIONAL_OBJECT_CATEGORY hr = pStore->SetGuidValue(WPD_FUNCTIONAL_OBJECT_CATEGORY, FunctionalCategory); CHECK_HR(hr, ("Failed to set WPD_FUNCTIONAL_OBJECT_CATEGORY")); } else if (IsEqualPropertyKey(Key, WPD_OBJECT_CONTAINER_FUNCTIONAL_OBJECT_ID)) { // Add WPD_OBJECT_CONTAINER_FUNCTIONAL_OBJECT_ID hr = pStore->SetStringValue(WPD_OBJECT_CONTAINER_FUNCTIONAL_OBJECT_ID, ContainerFunctionalObjectID); CHECK_HR(hr, ("Failed to set WPD_OBJECT_CONTAINER_FUNCTIONAL_OBJECT_ID")); } else if (IsEqualPropertyKey(Key, WPD_SERVICE_VERSION)) { // Add WPD_SERVICE_VERSION hr = pStore->SetStringValue(WPD_SERVICE_VERSION, Version); CHECK_HR(hr, ("Failed to set WPD_SERVICE_VERSION")); } else if (IsEqualPropertyKey(Key, PKEY_Services_ServiceDisplayName)) { pvValue = HumanReadableName; hr = pStore->SetValue(PKEY_Services_ServiceDisplayName, &pvValue); CHECK_HR(hr, ("Failed to set PKEY_Services_ServiceDisplayName")); } else if (IsEqualPropertyKey(Key, PKEY_FullEnumSyncSvc_SyncFormat)) { hr = pStore->SetGuidValue(PKEY_FullEnumSyncSvc_SyncFormat, PreferredSyncFormat); CHECK_HR(hr, ("Failed to set PKEY_FullEnumSyncSvc_SyncFormat")); } else if (IsEqualPropertyKey(Key, PKEY_Services_ServiceIcon)) { hr = GetIconData(pStore); CHECK_HR(hr, "Failed to set PKEY_Services_ServiceIcon"); } else if (IsEqualPropertyKey(Key, PKEY_FullEnumSyncSvc_VersionProps)) { hr = GetVICData(pStore); CHECK_HR(hr, "Failed to set PKEY_FullEnumSyncSvc_VersionProps"); } else { hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); CHECK_HR(hr, "Property {%ws}.%d is not supported", CComBSTR(Key.fmtid), Key.pid); } return hr; }
HRESULT CPyCOMTest::TestMyInterface( IUnknown *unktester) { if (!unktester) return E_POINTER; CComQIPtr<IPyCOMTest, &IID_IPyCOMTest> tester(unktester); if (!tester) return E_NOINTERFACE; HRESULT hr; // TEST QsBoolean i = 0, o = 0; CComVariant var(99); CHECK_HR(tester->Test( var, i, &o)); CHECK_TRUE( o ); i = 1, o = 1; CHECK_HR(tester->Test( var, i, &o)); CHECK_TRUE( !o ); // TEST2 QsAttribute ret_attr; QsAttribute attr = Attr1; CHECK_HR(tester->Test2( attr, &ret_attr)); CHECK_TRUE( attr == ret_attr ); attr = Attr3; CHECK_HR(tester->Test2( attr, &ret_attr)); CHECK_TRUE( attr == ret_attr ); // TEST6 QsAttributeWide ret_wideAttr; QsAttributeWide wideAttr; wideAttr = WideAttr1; CHECK_HR(tester->Test6( wideAttr, &ret_wideAttr)); CHECK_TRUE( wideAttr == ret_wideAttr ); wideAttr = WideAttr2; CHECK_HR(tester->Test6( wideAttr, &ret_wideAttr)); CHECK_TRUE( wideAttr == ret_wideAttr ); wideAttr = WideAttr3; CHECK_HR(tester->Test6( wideAttr, &ret_wideAttr)); CHECK_TRUE( wideAttr == ret_wideAttr ); wideAttr = WideAttr4; CHECK_HR(tester->Test6( wideAttr, &ret_wideAttr)); CHECK_TRUE( wideAttr == ret_wideAttr ); wideAttr = WideAttr5; CHECK_HR(tester->Test6( wideAttr, &ret_wideAttr)); CHECK_TRUE( wideAttr == ret_wideAttr ); // TEST5 TestAttributes1 tattr = TestAttr1; CHECK_HR(tester->Test5( &tattr )); CHECK_TRUE( tattr == TestAttr1_1 ); tattr = TestAttr1_1; CHECK_HR(tester->Test5( &tattr )); CHECK_TRUE( tattr == TestAttr1 ); // STRINGS CComBSTR instr("Foo"); CComBSTR outstr; CHECK_HR(tester->DoubleString(instr, &outstr)); CHECK_TRUE(outstr == L"FooFoo"); instr = L"Foo"; CHECK_HR(tester->TestByRefString(&instr)); CHECK_TRUE(instr == L"FooFoo"); // Arrays int result; SAFEARRAY *array; CHECK_HR(MakeFillIntArray(&array, 5, VT_INT)); CHECK_HR(tester->CheckVariantSafeArray(&array, &result)); CHECK_TRUE(result==1); CHECK_HR(tester->SetIntSafeArray(array, &result)); SafeArrayDestroy(array); CHECK_HR(MakeFillIntArray(&array, 5, VT_I8)); CHECK_HR(tester->CheckVariantSafeArray(&array, &result)); CHECK_TRUE(result==1); CHECK_HR(tester->SetLongLongSafeArray(array, &result)); SafeArrayDestroy(array); CHECK_HR(MakeFillIntArray(&array, 5, VT_UI8)); CHECK_HR(tester->CheckVariantSafeArray(&array, &result)); CHECK_TRUE(result==1); CHECK_HR(tester->SetULongLongSafeArray(array, &result)); SafeArrayDestroy(array); long lresult; CHECK_HR(tester->put_LongProp(4)); CHECK_HR(tester->get_LongProp(&lresult)); CHECK_TRUE(lresult==4); CHECK_HR(tester->put_LongProp(-4)); CHECK_HR(tester->get_LongProp(&lresult)); CHECK_TRUE(lresult==-4); unsigned long ulresult; CHECK_HR(tester->put_ULongProp(0x80000001)); CHECK_HR(tester->get_ULongProp(&ulresult)); CHECK_TRUE(ulresult==0x80000001); CHECK_HR(tester->put_IntProp(4)); CHECK_HR(tester->get_IntProp(&result)); CHECK_TRUE(result==4); CY cy = {123, 456}; CY cresult; CHECK_HR(tester->put_CurrencyProp(cy)); CHECK_HR(tester->get_CurrencyProp(&cresult)); CHECK_TRUE(cresult.int64==cy.int64); // interface tests CComPtr<IPyCOMTest>param(tester); CComPtr<IPyCOMTest>obresult; CHECK_HR(tester->GetSetInterface(param, &obresult)); VARIANT v1, v2; VariantInit(&v1); VariantInit(&v2); V_VT(&v1) = VT_I4; V_I4(&v1) = 99; CHECK_HR(tester->GetSetVariant(v1, &v2)); CHECK_TRUE(V_VT(&v2)==VT_I4); CHECK_TRUE(V_I4(&v2)==99); CHECK_HR(tester->TestByRefVariant(&v2)); CHECK_TRUE(V_VT(&v2)==VT_I4); CHECK_TRUE(V_I4(&v2)==198); VariantClear(&v1); VariantClear(&v2); // Make a vtable call on the returned object, so we // crash if a bad vtable. Don't care about the value tho. CHECK_HR(obresult->get_IntProp(&result)); return S_OK; }