/////////////////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 1996 Microsoft Corporation // // Module Name: capolicy.cpp // // Abstract: // // Implements ICAPolicy interface // Also handles registration of the plugin DLL and communication // with the filter driver. // // //////////////////////////////////////////////////////////////////////////////////////////// #include "pch.h" #include "capolicy.h" #include "podprotocol.h" #ifdef _MERGE_PROXYSTUB extern "C" HINSTANCE hProxyDll; #endif CComModule _Module; BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(__uuidof(PODProtocol), CPODProtocol) END_OBJECT_MAP() //////////////////////////////////////////////////////////////////////////////////////////// // // Provide the ActiveMovie templates for classes supported by this DLL. // CFactoryTemplate g_Templates[] = { {L"caplugin", &KSPROPSETID_BdaCA, CBdaECMMapInterfaceHandler::CreateInstance, NULL, NULL} }; int g_cTemplates = SIZEOF_ARRAY(g_Templates); ///////////////////////////////////////////////////////////////////////////// // DLL Entry Point extern "C" BOOL WINAPI AMovieDllEntryPoint(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved); extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { lpReserved; #ifdef _MERGE_PROXYSTUB if (!PrxDllMain(hInstance, dwReason, lpReserved)) return FALSE; #endif if (dwReason == DLL_PROCESS_ATTACH) { _Module.Init(ObjectMap, hInstance, &LIBID_POD); DisableThreadLibraryCalls(hInstance); } else if (dwReason == DLL_PROCESS_DETACH) _Module.Term(); return AMovieDllEntryPoint(hInstance, dwReason, lpReserved); } /////////////////////////////////////////////////////////////////////////////// // // DllRegisterServer // // Exported entry points for registration and unregistration // STDAPI DllRegisterServer ( void ) { HRESULT hr; #ifdef _MERGE_PROXYSTUB hr = PrxDllRegisterServer(); if (FAILED(hr)) return hr; #endif // registers object, typelib and all interfaces in typelib hr = _Module.RegisterServer(TRUE); if (FAILED(hr)) return hr; return AMovieDllRegisterServer2( TRUE ); } /////////////////////////////////////////////////////////////////////////////// // // DllUnregisterServer // STDAPI DllUnregisterServer ( void ) /////////////////////////////////////////////////////////////////////////////// { #ifdef _MERGE_PROXYSTUB PrxDllUnregisterServer(); #endif HRESULT hr = _Module.UnregisterServer(TRUE); if (FAILED(hr)) return hr; return AMovieDllRegisterServer2( FALSE ); } // DllUnregisterServer STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { HRESULT hr; HRESULT AMovieDllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv); hr = AMovieDllGetClassObject(rclsid, riid, ppv); if (SUCCEEDED(hr)) return hr; #ifdef _MERGE_PROXYSTUB if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK) return S_OK; #endif return _Module.GetClassObject(rclsid, riid, ppv); } //////////////////////////////////////////////////////////////////////////////////////////// // // CreateInstance // // create a new instance of our class // CUnknown* CALLBACK CBdaECMMapInterfaceHandler::CreateInstance( LPUNKNOWN UnkOuter, HRESULT* hr ) //////////////////////////////////////////////////////////////////////////////////////////// { CUnknown *Unknown; Unknown = (CUnknown *)new CBdaECMMapInterfaceHandler(UnkOuter, NAME("IBDA_ECMMap"), hr); if (!Unknown) *hr = E_OUTOFMEMORY; return Unknown; } //////////////////////////////////////////////////////////////////////////////////////////// // // NonDelegatingQueryInterface // // if they want an ICAPolicy or IBDA_ECMMap interface, just AddRef the parent // with GetInterface and pass back a pointer to this. // STDMETHODIMP CBdaECMMapInterfaceHandler::NonDelegatingQueryInterface( REFIID riid, PVOID* ppv ) //////////////////////////////////////////////////////////////////////////////////////////// { if (riid == __uuidof(ICAPolicy)) { return GetInterface(static_cast(this), ppv); } #ifdef IMPLEMENT_IBDA_ECMMap if (riid == __uuidof(IBDA_ECMMap)) { return GetInterface(static_cast(this), ppv); } #endif return CUnknown::NonDelegatingQueryInterface(riid, ppv); } //////////////////////////////////////////////////////////////////////////////////////////// // // CBdaECMMapInterfaceHandler // // class constructor, gets handle to underlying CA driver and starts thread // CBdaECMMapInterfaceHandler::CBdaECMMapInterfaceHandler( LPUNKNOWN UnkOuter, TCHAR* Name, HRESULT* hr ) : CUnknown( Name, UnkOuter, hr) { m_pCAMan = NULL; m_UnkOuter = UnkOuter; m_ppodprot = NULL; if (SUCCEEDED(*hr)) { if (UnkOuter) { #if IMPLEMENT_PODPROTOCOL //BUGBUG - Hack to make sure pod protocol knows how to talk to us. *hr = CoCreateInstance(__uuidof(PODProtocol), NULL, CLSCTX_ALL, __uuidof(IPODProtocol), (void **)&m_ppodprot); if (FAILED(*hr)) return; *hr = m_ppodprot->put_CAPod((ICAPod *) this); if (FAILED(*hr)) return; #endif IKsObject* Object = NULL; // // The parent must support this interface in order to obtain // the handle to communicate to. // *hr = UnkOuter->QueryInterface(__uuidof(IKsObject), reinterpret_cast(&Object)); if (FAILED (*hr)) return; m_ObjectHandle = Object->KsGetObjectHandle (); if (!m_ObjectHandle) { *hr = E_UNEXPECTED; return; } Object->Release(); //init thread handle and event handles to NULL m_ThreadHandle = NULL; for (int ul = 0; ul < EVENT_COUNT; ul++) m_EventHandle [ul] = NULL; //now start thread *hr = CreateThread (); if(FAILED(*hr)) return; } else *hr = VFW_E_NEED_OWNER; } } //////////////////////////////////////////////////////////////////////////////////////////// // // ConnectToCAManager // // HRESULT CBdaECMMapInterfaceHandler::ConnectToCAManager() { HRESULT hr = NOERROR; // Find the CA Manager on the graph and add our policy. // if (!m_pGraph) { // Find the Graph } if (m_pGraph) { CComPtr pQS; hr = m_pGraph->QueryInterface( __uuidof( IServiceProvider), (void **) &pQS ); if (FAILED(hr)) { goto errExit; } hr = pQS->QueryService(__uuidof(CAManager), __uuidof( ICAManager), (void **) &m_pCAMan ); if (FAILED(hr)) { goto errExit; } CComPtr ppolicies; hr = m_pCAMan->get_Policies(&ppolicies); if (FAILED(hr)) goto errExit; hr = ppolicies->Add(this); if (FAILED(hr)) goto errExit; } else { hr = E_NOINTERFACE; } errExit: return hr; } //////////////////////////////////////////////////////////////////////////////////////////// // // ~CBdaECMMapInterfaceHandler // // destructor, terminates thread // CBdaECMMapInterfaceHandler::~CBdaECMMapInterfaceHandler() { ULONG ul = 0; // // Make sure we kill any threads we have running and // close the thread handle // if (m_ThreadHandle) { TerminateThread (m_ThreadHandle, 0); CloseHandle(m_ThreadHandle); m_ThreadHandle = NULL; } // // Close the event handle // for (ul = 0; ul < EVENT_COUNT; ul++) { if (m_EventHandle [ul]) { CloseHandle(m_EventHandle [ul]); m_EventHandle [ul] = NULL; } } if (m_ppodprot != NULL) m_ppodprot->Release(); } //////////////////////////////////////////////////////////////////////////////////////////// // // get_Name // // ICAPolicy interface function, returns policy name // STDMETHODIMP CBdaECMMapInterfaceHandler::get_Name(BSTR * pbstr) { if (pbstr == NULL) return E_POINTER; *pbstr = SysAllocString(L"CA Policy Object"); if ((*pbstr) == NULL) return E_OUTOFMEMORY; return NOERROR; } //////////////////////////////////////////////////////////////////////////////////////////// // // get_OkToRemove // // ICAPolicy interface function, returns whether or not it is alright to remove this policy // STDMETHODIMP CBdaECMMapInterfaceHandler::get_OkToRemove(BOOL * pfOkToRemove) { if (pfOkToRemove == NULL) return E_POINTER; *pfOkToRemove = false; return NOERROR; } //////////////////////////////////////////////////////////////////////////////////////////// // // CheckRequest // // ICAPolicy interface function, checks a tuneing request // STDMETHODIMP CBdaECMMapInterfaceHandler::CheckRequest(ICARequest * preq) { //TO DO: if you want to check individual requests, this is the place to do it return NOERROR; } //////////////////////////////////////////////////////////////////////////////////////////// // // NavigateURL // // ICAPolicy interface function // STDMETHODIMP CBdaECMMapInterfaceHandler::NavigateURL(BSTR bstrURL) { return E_NOTIMPL; } //////////////////////////////////////////////////////////////////////////////////////////// // // get_OkToRemoveDenial // // ICAPolicy interface function, checks whether it is ok to remove a denial // STDMETHODIMP CBdaECMMapInterfaceHandler::get_OkToRemoveDenial(ICADenial * pdenial, BOOL * pVal) { if (pVal == NULL) return E_POINTER; return E_NOTIMPL; } //////////////////////////////////////////////////////////////////////////////////////////// // // Set // pProp = description of the property item to set // pvBuffer = pointer to data to set // ulcbSize = size of data to set // // set a KSPROPERTY item's data // STDMETHODIMP CBdaECMMapInterfaceHandler::Set(PKSPROPERTY pProp, PVOID pvBuffer, ULONG *ulcbSize) { ULONG BytesReturned = 0; HRESULT hr = NOERROR; hr = ::KsSynchronousDeviceControl( m_ObjectHandle, IOCTL_KS_PROPERTY, (PVOID) pProp, sizeof(KSPROPERTY), pvBuffer, *ulcbSize, &BytesReturned); *ulcbSize = BytesReturned; return hr; } //////////////////////////////////////////////////////////////////////////////////////////// // // Get // pProp = description of the property item to get // pvBuffer = place to put data once retrieved // pulcbSize = size of data retrieved // // get a KSPROPERTY item's data // STDMETHODIMP CBdaECMMapInterfaceHandler::Get(PKSPROPERTY pProp, PVOID pvBuffer, PULONG pulcbSize) { ULONG BytesReturned = 0; HRESULT hr = NOERROR; hr = ::KsSynchronousDeviceControl( m_ObjectHandle, IOCTL_KS_PROPERTY, (PVOID) pProp, sizeof(KSPROPERTY), pvBuffer, *pulcbSize, &BytesReturned); *pulcbSize = BytesReturned; return hr; } //////////////////////////////////////////////////////////////////////////////////////////// // // CreateThread // // create the thread to catch events from the driver // STDMETHODIMP CBdaECMMapInterfaceHandler::CreateThread() //////////////////////////////////////////////////////////////////////////////////////////// { HRESULT hr = NOERROR; if (m_ThreadHandle == NULL) { DWORD ThreadId; m_ThreadHandle = ::CreateThread ( NULL, 0, ThreadFunctionWrapper, (LPVOID) this, 0, (LPDWORD) &ThreadId ); if (m_ThreadHandle == NULL) { hr = HRESULT_FROM_WIN32 (GetLastError()); } } return hr; } //////////////////////////////////////////////////////////////////////////////////////////// // // GetCAModuleUI // ulFormat = format of the required data // ppUI = pointer to a pointer to the UI data // pulcbUI = pointer to ULONG to store UI data size in // // Get UI data from CA Module via driver // STDMETHODIMP CBdaECMMapInterfaceHandler::GetCAModuleUI(ULONG ulFormat, PBDA_CA_MODULE_UI *ppUI, unsigned long *pulcbUI) /////////////////////////////////////////////////////////////////////////////////////////// { KSPROPERTY Prop = {0}; HRESULT hr = NOERROR; unsigned long ulcbUIAllocated; if(ppUI == NULL) return E_POINTER; if(pulcbUI == NULL) return E_POINTER; // // Initialize KSPROPERTY structure // Prop.Set = KSPROPSETID_BdaCA; Prop.Id = KSPROPERTY_BDA_CA_MODULE_UI; Prop.Flags = KSPROPERTY_TYPE_GET; *ppUI = new BDA_CA_MODULE_UI; *pulcbUI = ulcbUIAllocated = sizeof(BDA_CA_MODULE_UI); do { (*ppUI)->ulFormat = ulFormat; //BUGBUG : tcpr review... is this really in/out? hr = this->Get (&Prop, *ppUI, pulcbUI); if (HRESULT_CODE (hr) == ERROR_MORE_DATA) { if ( (*pulcbUI) > ulcbUIAllocated) { if ( (*ppUI) ) { delete ( (*ppUI) ); } ulcbUIAllocated = (*pulcbUI); (*ppUI) = (PBDA_CA_MODULE_UI) new BYTE [ulcbUIAllocated]; if ( (*ppUI) == NULL) { hr = ERROR_NOT_ENOUGH_MEMORY; goto ret; } } } } while (HRESULT_CODE (hr) == ERROR_MORE_DATA); ret: return hr; } //////////////////////////////////////////////////////////////////////////////////////////// // // SetGetCAModuleUI // ulFormat = format of the required data // pbDataIn = data to send to the driver. // ppUI = pointer to a pointer to the UI data // pulcbUI = pointer to ULONG to store UI data size in // // Get UI data from CA Module via driver // STDMETHODIMP CBdaECMMapInterfaceHandler::SetGetCAModuleUI(ULONG ulFormat, BYTE *pbDataIn, long cbDataIn, PBDA_CA_MODULE_UI *ppUI, unsigned long *pulcbUI) /////////////////////////////////////////////////////////////////////////////////////////// { KSPROPERTY Prop = {0}; HRESULT hr = NOERROR; unsigned long ulcbUIAllocated; if(ppUI == NULL) return E_POINTER; if(pulcbUI == NULL) return E_POINTER; // // Initialize KSPROPERTY structure // Prop.Set = KSPROPSETID_BdaCA; Prop.Id = KSPROPERTY_BDA_CA_MODULE_UI; Prop.Flags = KSPROPERTY_TYPE_GET; *ppUI = new BDA_CA_MODULE_UI; *pulcbUI = ulcbUIAllocated = sizeof(BDA_CA_MODULE_UI) + cbDataIn; do { (*ppUI)->ulFormat = ulFormat; memcpy((*ppUI)->ulDesc, pbDataIn, cbDataIn); hr = this->Get (&Prop, *ppUI, pulcbUI); if (HRESULT_CODE (hr) == ERROR_MORE_DATA) { if ( (*pulcbUI) > ulcbUIAllocated) { if ( (*ppUI) ) { delete ( (*ppUI) ); } ulcbUIAllocated = (*pulcbUI); (*ppUI) = (PBDA_CA_MODULE_UI) new BYTE [ulcbUIAllocated]; if ( (*ppUI) == NULL) { hr = ERROR_NOT_ENOUGH_MEMORY; goto ret; } } } } while (HRESULT_CODE (hr) == ERROR_MORE_DATA); ret: return hr; } //////////////////////////////////////////////////////////////////////////////////////////// // // GetECMMapStatus // pStatus = ULONG to store status in once retrieved // // Gets the ECMMap status from the driver // STDMETHODIMP CBdaECMMapInterfaceHandler::GetECMMapStatus(unsigned long *pStatus) //////////////////////////////////////////////////////////////////////////////////////////// { KSPROPERTY Prop = {0}; unsigned long ulcbJunk; if(pStatus == NULL) return E_POINTER; // // Initialize KSPROPERTY structure // Prop.Set = KSPROPSETID_BdaCA; Prop.Id = KSPROPERTY_BDA_ECM_MAP_STATUS; Prop.Flags = KSPROPERTY_TYPE_GET; return this->Get (&Prop, pStatus, &ulcbJunk); } //////////////////////////////////////////////////////////////////////////////////////////// // // GetCAModuleStatus // pStatus = ULONG to store status in once retrieved // // Gets the CA Module status from the driver // STDMETHODIMP CBdaECMMapInterfaceHandler::GetCAModuleStatus (unsigned long *pStatus) //////////////////////////////////////////////////////////////////////////////////////////// { KSPROPERTY Prop = {0}; unsigned long ulcbJunk; if(pStatus == NULL) return E_POINTER; // // Initialize KSPROPERTY structure // Prop.Set = KSPROPSETID_BdaCA; Prop.Id = KSPROPERTY_BDA_CA_MODULE_STATUS; Prop.Flags = KSPROPERTY_TYPE_GET; return this->Get (&Prop, pStatus, &ulcbJunk); } //////////////////////////////////////////////////////////////////////////////////////////// // // GetCASmartCardStatus // pStatus = ULONG to store status in once retrieved // // Gets the CA SmartCard status from the driver // STDMETHODIMP CBdaECMMapInterfaceHandler::GetCASmartCardStatus (unsigned long *pStatus) //////////////////////////////////////////////////////////////////////////////////////////// { KSPROPERTY Prop = {0}; unsigned long ulcbJunk; if(pStatus == NULL) return E_POINTER; // // Initialize KSPROPERTY structure // Prop.Set = KSPROPSETID_BdaCA; Prop.Id = KSPROPERTY_BDA_CA_SMART_CARD_STATUS; Prop.Flags = KSPROPERTY_TYPE_GET; return this->Get (&Prop, pStatus, &ulcbJunk); } //////////////////////////////////////////////////////////////////////////////////////////// // // ThreadFunction // // thread function to initialize and handle the thread that catches // events generated by the CA driver // STDMETHODIMP CBdaECMMapInterfaceHandler::ThreadFunction () //////////////////////////////////////////////////////////////////////////////////////////// { DWORD dwWaitResult = WAIT_OBJECT_0; HRESULT hr = NOERROR; HANDLE hEvent = NULL; // // this code enables each of the four CA events we will be catching by calling // EnableEvent specifying the individual event id's // #if 0 if ((hr = EnableEvent (&KSEVENTSETID_BdaCAEvent, KSEVENT_BDA_ECM_MAP_STATUS_CHANGED)) != NOERROR) { goto ret; } #endif if ((hr = EnableEvent (&KSEVENTSETID_BdaCAEvent, KSEVENT_BDA_CA_MODULE_STATUS_CHANGED)) != NOERROR) { CloseHandle (m_EventHandle [KSEVENT_BDA_ECM_MAP_STATUS_CHANGED]); // Close this event since we got an error. goto ret; } if ((hr = EnableEvent (&KSEVENTSETID_BdaCAEvent, KSEVENT_BDA_CA_SMART_CARD_STATUS_CHANGED)) != NOERROR) { CloseHandle (m_EventHandle [KSEVENT_BDA_ECM_MAP_STATUS_CHANGED]); // Close this event since we got an error. CloseHandle (m_EventHandle [KSEVENT_BDA_CA_MODULE_STATUS_CHANGED]); // Close this event since we got an error. goto ret; } if ((hr = EnableEvent (&KSEVENTSETID_BdaCAEvent, KSEVENT_BDA_CA_MODULE_UI_REQUESTED)) != NOERROR) { CloseHandle (m_EventHandle [KSEVENT_BDA_ECM_MAP_STATUS_CHANGED]); // Close this event since we got an error. CloseHandle (m_EventHandle [KSEVENT_BDA_CA_MODULE_STATUS_CHANGED]); // Close this event since we got an error. CloseHandle (m_EventHandle [KSEVENT_BDA_CA_SMART_CARD_STATUS_CHANGED]); // Close this event since we got an error. goto ret; } // the following infinite loop waits for events and responds to recieved ones do { //wait for the next event... dwWaitResult = WaitForMultipleObjects ( EVENT_COUNT, // number of handles in the handle array this->m_EventHandle, // pointer to the object-handle array FALSE, // wait flag INFINITE ); //if something went ary, get the error and return if (dwWaitResult == WAIT_FAILED) { dwWaitResult = GetLastError (); hr = E_FAIL; goto ret; } //get a pointer to the event so we can reset it later hEvent = this->m_EventHandle [dwWaitResult - WAIT_OBJECT_0]; //depending on the type of event, respond accordingly switch (dwWaitResult - WAIT_OBJECT_0) { #if 0 case KSEVENT_BDA_ECM_MAP_STATUS_CHANGED: //update the local status variable with the new status hr = GetECMMapStatus(&m_ECMMapStatus); break; #endif case KSEVENT_BDA_CA_MODULE_STATUS_CHANGED: //update the local status variable with the new status hr = GetCAModuleStatus(&m_CAModuleStatus); break; case KSEVENT_BDA_CA_SMART_CARD_STATUS_CHANGED: //update the local status variable with the new status hr = GetCASmartCardStatus(&m_CASmartCardStatus); break; case KSEVENT_BDA_CA_MODULE_UI_REQUESTED: //the CA module wants to display a UI, so let it do so hr = ProcessCAModuleUI(); break; default: //in case of unknown event, return goto ret; break; } // // Reset and get ready for the next event // if (ResetEvent (hEvent) == FALSE) { // // ERROR detected resetting event // hr = GetLastError (); goto ret; } } while (TRUE); ret: return hr; } //////////////////////////////////////////////////////////////////////////////////////////// // // ThreadFunctionWrapper // // global thread wrapping function // DWORD WINAPI CBdaECMMapInterfaceHandler::ThreadFunctionWrapper ( LPVOID pvParam ) //////////////////////////////////////////////////////////////////////////////////////////// { CBdaECMMapInterfaceHandler *pThread; pThread = (CBdaECMMapInterfaceHandler *) pvParam; return pThread->ThreadFunction (); } //////////////////////////////////////////////////////////////////////////////////////////// // // EnableEvent // pInterfaceGuid = the GUID of the event set which contains the event // ulId = the ID of the event in the event set // // enable a particular event // STDMETHODIMP CBdaECMMapInterfaceHandler::EnableEvent (const GUID *pInterfaceGuid, ULONG ulId) //////////////////////////////////////////////////////////////////////////////////////////// { HRESULT hr = NOERROR; KSEVENT Event; KSEVENTDATA EventData; DWORD BytesReturned; if (m_ObjectHandle && m_EventHandle [ulId] == NULL) { this->m_EventHandle [ulId] = CreateEvent ( NULL, // no security attributes TRUE, // manual reset FALSE, // initial state not signaled NULL // no object name ); if (this->m_EventHandle [ulId]) { // // Set the event information into some KS structures which will // get passed to KS and Streaming class // EventData.NotificationType = KSEVENTF_EVENT_HANDLE; EventData.EventHandle.Event = this->m_EventHandle [ulId]; EventData.EventHandle.Reserved[0] = 0; EventData.EventHandle.Reserved[1] = 0; Event.Set = *pInterfaceGuid; //IID_ICAPolicy; Event.Id = ulId; Event.Flags = KSEVENT_TYPE_ENABLE; hr = ::KsSynchronousDeviceControl ( m_ObjectHandle, IOCTL_KS_ENABLE_EVENT, &Event, sizeof(Event), &EventData, sizeof(EventData), &BytesReturned ); } } return hr; } //////////////////////////////////////////////////////////////////////////////////////////// // // ExitThread // // kill the event catching thread // void CBdaECMMapInterfaceHandler::ExitThread() //////////////////////////////////////////////////////////////////////////////////////////// { ULONG ul = 0; if (m_ThreadHandle) { for (ul = 0; ul < EVENT_COUNT; ul++) { // // Tell the thread to exit // if (SetEvent(m_EventHandle [ul])) { // // Synchronize with thread termination. // WaitForSingleObjectEx(m_ThreadHandle, INFINITE, FALSE); } if (m_EventHandle [ul] != NULL) { CloseHandle(m_EventHandle [ul]), m_EventHandle [ul] = NULL; } } CloseHandle(m_ThreadHandle), m_ThreadHandle = NULL; } } ///////////////////////////////////////////////////////////////////////////// // // ProcessCAModuleUI // // get the UI from the CA Module and display it // STDMETHODIMP CBdaECMMapInterfaceHandler::ProcessCAModuleUI() { PBDA_CA_MODULE_UI pUI; unsigned long ulcbUI; HRESULT hr; //TO DO: this function is just a simple dump of the UI //more code is needed here for the particular UI desired //for example if HTML is to be displayed something needs //to be done here. //get UI from CA Module hr = GetCAModuleUI(1, &pUI, &ulcbUI); //BUGBUG tcpr review... ulFormat== 1 means URL if(FAILED(hr)) return hr; return RegisterDenial((char *)pUI->ulDesc); } ///////////////////////////////////////////////////////////////////////////// // // RegisterDenial // // STDMETHODIMP CBdaECMMapInterfaceHandler::RegisterDenial(char *szURL) { ICARequest *pActiveRequest = NULL; ICADenials *pActiveRequestDenials = NULL; ICADenial *pDenial = NULL; #ifdef IMPLEMENT_TOLL ICATolls *pDenialTolls = NULL; CMyToll *pOurToll = NULL; #endif HRESULT hr = NOERROR; if(m_pCAMan == NULL) return E_FAIL; //get the active request from the CA manager hr = m_pCAMan->get_ActiveRequest(&pActiveRequest); if(FAILED(hr)) return hr; if(pActiveRequest == NULL) return E_FAIL; //get the list of denials from the CA manager hr = pActiveRequest->get_Denials(&pActiveRequestDenials); if(FAILED(hr)) return hr; if(pActiveRequestDenials == NULL) return E_FAIL; //add a new denial BSTR bstrDesc; bstrDesc = SysAllocString(L"Access denied"); hr = pActiveRequestDenials->get_AddNew((ICAPolicy *)this, bstrDesc, pActiveRequest, 0, &pDenial); if(FAILED(hr)) return hr; if(pDenial == NULL) return E_FAIL; CComBSTR bstrURL(szURL); pDenial->put_Description(URL, bstrURL); #ifdef IMPLEMENT_TOLL //get the list of tolls associated with the denial hr = pDenial->get_Tolls(&pDenialTolls); if(FAILED(hr)) return hr; if(pDenialTolls == NULL) return E_FAIL; pOurToll = new CMyToll(m_UnkOuter, NAME("ICAToll"), &hr); if(FAILED(hr)) return hr; if(pOurToll == NULL) return E_FAIL; //set the associated policy to ourselves hr = pOurToll->set_Policy((ICAPolicy *)this); if(FAILED(hr)) return hr; //set the associated request to the active one hr = pOurToll->set_Request(pActiveRequest); if(FAILED(hr)) return hr; //add our toll to the list on the denial return pDenialTolls->Add((ICAToll *)pOurToll); #else return S_OK; #endif } #ifdef IMPLEMENT_IBDA_ECMMap //////////////////////////////////////////////////////////////////////////////////////////// // // SetEmmPid // // maps through to KSProperty item // STDMETHODIMP CBdaECMMapInterfaceHandler::SetEmmPid(ULONG Pid) { HRESULT hrStatus = NOERROR; KSPROPERTY kspECMMap; ULONG ulcbReturned = 0; kspECMMap.Set = KSPROPSETID_BdaEcmMap; kspECMMap.Id = KSPROPERTY_BDA_ECMMAP_EMM_PID; kspECMMap.Flags = KSPROPERTY_TYPE_SET; hrStatus = ::KsSynchronousDeviceControl( m_ObjectHandle, IOCTL_KS_PROPERTY, (PVOID) &kspECMMap, sizeof( KSPROPERTY), (PVOID) &Pid, sizeof( ULONG), &ulcbReturned ); return hrStatus; } //////////////////////////////////////////////////////////////////////////////////////////// // // GetEcmMapList // // maps through to KSProperty item // STDMETHODIMP CBdaECMMapInterfaceHandler::GetEcmMapList(PBDA_ECM_MAP *ppList, ULONG *pulcbReturned) { HRESULT hrStatus = NOERROR; KSPROPERTY kspECMMap; ULONG ulcbAllocated = 0; if(ppList == NULL) return E_POINTER; if(pulcbReturned == NULL) return E_POINTER; // // Initialize KSPROPERTY structure // kspECMMap.Set = KSPROPSETID_BdaEcmMap; kspECMMap.Id = KSPROPERTY_BDA_ECMMAP_MAP_LIST; kspECMMap.Flags = KSPROPERTY_TYPE_GET; *ppList = new BDA_ECM_MAP; *pulcbReturned = ulcbAllocated = sizeof(BDA_ECM_MAP); do { hrStatus = ::KsSynchronousDeviceControl( m_ObjectHandle, IOCTL_KS_PROPERTY, (PVOID) &kspECMMap, sizeof( KSPROPERTY), (PVOID) *ppList, *pulcbReturned, pulcbReturned ); if (HRESULT_CODE (hrStatus) == ERROR_MORE_DATA) { if ( (*pulcbReturned) > ulcbAllocated) { if ( (*ppList) ) { delete ( (*ppList) ); } ulcbAllocated = (*pulcbReturned); (*ppList) = (PBDA_ECM_MAP) new BYTE [ulcbAllocated]; if ( (*ppList) == NULL) { hrStatus = ERROR_NOT_ENOUGH_MEMORY; goto ret; } } } } while (HRESULT_CODE (hrStatus) == ERROR_MORE_DATA); ret: return hrStatus; } //////////////////////////////////////////////////////////////////////////////////////////// // // UpdateEcmMap // // maps through to KSProperty item // STDMETHODIMP CBdaECMMapInterfaceHandler::UpdateEcmMap(PBDA_ECM_MAP pMap) { HRESULT hrStatus = NOERROR; KSPROPERTY kspECMMap; ULONG ulcbReturned = 0; kspECMMap.Set = KSPROPSETID_BdaEcmMap; kspECMMap.Id = KSPROPERTY_BDA_ECMMAP_UPDATE_MAP; kspECMMap.Flags = KSPROPERTY_TYPE_SET; hrStatus = ::KsSynchronousDeviceControl( m_ObjectHandle, IOCTL_KS_PROPERTY, (PVOID) &kspECMMap, sizeof( KSPROPERTY), (PVOID) pMap, sizeof( BDA_ECM_MAP), &ulcbReturned ); return hrStatus; } //////////////////////////////////////////////////////////////////////////////////////////// // // RemoveMap // // maps through to KSProperty item // STDMETHODIMP CBdaECMMapInterfaceHandler::RemoveMap(PBDA_ECM_MAP pMap) { HRESULT hrStatus = NOERROR; KSPROPERTY kspECMMap; ULONG ulcbReturned = 0; kspECMMap.Set = KSPROPSETID_BdaEcmMap; kspECMMap.Id = KSPROPERTY_BDA_ECMMAP_REMOVE_MAP; kspECMMap.Flags = KSPROPERTY_TYPE_SET; hrStatus = ::KsSynchronousDeviceControl( m_ObjectHandle, IOCTL_KS_PROPERTY, (PVOID) &kspECMMap, sizeof( KSPROPERTY), (PVOID) pMap, sizeof( BDA_ECM_MAP), &ulcbReturned ); return hrStatus; } //////////////////////////////////////////////////////////////////////////////////////////// // // UpdateESDescriptor // // maps through to KSProperty item // STDMETHODIMP CBdaECMMapInterfaceHandler::UpdateESDescriptor(PBDA_ES_DESCRIPTOR pDesc) { HRESULT hrStatus = NOERROR; KSPROPERTY kspECMMap; ULONG ulcbReturned = 0; kspECMMap.Set = KSPROPSETID_BdaEcmMap; kspECMMap.Id = KSPROPERTY_BDA_ECMMAP_UPDATE_ES_DESCRIPTOR; kspECMMap.Flags = KSPROPERTY_TYPE_SET; hrStatus = ::KsSynchronousDeviceControl( m_ObjectHandle, IOCTL_KS_PROPERTY, (PVOID) &kspECMMap, sizeof( KSPROPERTY), (PVOID) pDesc, sizeof( BDA_ES_DESCRIPTOR), &ulcbReturned ); return hrStatus; } //////////////////////////////////////////////////////////////////////////////////////////// // // UpdateProgramDescriptor // // maps through to KSProperty item // STDMETHODIMP CBdaECMMapInterfaceHandler::UpdateProgramDescriptor(PBDA_PROGRAM_DESCRIPTOR pDesc) { HRESULT hrStatus = NOERROR; KSPROPERTY kspECMMap; ULONG ulcbReturned = 0; kspECMMap.Set = KSPROPSETID_BdaEcmMap; kspECMMap.Id = KSPROPERTY_BDA_ECMMAP_UPDATE_PROGRAM_DESCRIPTOR; kspECMMap.Flags = KSPROPERTY_TYPE_SET; hrStatus = ::KsSynchronousDeviceControl( m_ObjectHandle, IOCTL_KS_PROPERTY, (PVOID) &kspECMMap, sizeof( KSPROPERTY), (PVOID) pDesc, sizeof( BDA_PROGRAM_DESCRIPTOR), &ulcbReturned ); return hrStatus; } #endif