예제 #1
0
TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
{
  TInt r=KErrNone;
  switch(aFunction)
	{
	case EDisplayHalScreenInfo:
	  {
		TPckgBuf<TScreenInfoV01> vPckg;
		ScreenInfo(vPckg());
		Kern::InfoCopy(*(TDes8*)a1,vPckg);
		break;
	  }
	case EDisplayHalWsRegisterSwitchOnScreenHandling:
	  {
		iWsSwitchOnScreen=(TBool)a1;
		break;
	  }
	case EDisplayHalWsSwitchOnScreen:
	  {
		WsSwitchOnScreen();
		break;
	  }
	case EDisplayHalModeCount:
	  {
		TInt ndm = KConfigLcdNumberOfDisplayModes;
		kumemput32(a1, &ndm, sizeof(ndm));
		break;
	  }
	case EDisplayHalSetMode:
	  {
		__KTRACE_OPT(KEXTENSION,Kern::Printf("EDisplayHalSetMode"));
		__SECURE_KERNEL(
						if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode")))
						return KErrPermissionDenied;
						)
		  r = SetDisplayMode((TInt)a1);
		break;
	  }
	case EDisplayHalMode:
	  {
		kumemput32(a1, &iVideoInfo.iDisplayMode, sizeof(iVideoInfo.iDisplayMode));
		r = KErrNone;
		break;
	  }
	case EDisplayHalSetPaletteEntry:
	  {
		__SECURE_KERNEL(
						if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetPaletteEntry")))
						return KErrPermissionDenied;
						)
		  r = KErrNotSupported;
		break;
	  }
MSsmSwpPolicy::TResponse CRFStatusSwPPolicy ::TransitionAllowed(const TSsmSwp& aSwp, const RMessagePtr2& aMessage)
	{
	MSsmSwpPolicy::TResponse isTransitionAllowed = ENotAllowed;   
	TBool hasCapability = aMessage.HasCapability(ECapabilityWriteDeviceData, ECapabilityPowerMgmt,
	                    __PLATSEC_DIAGNOSTIC_STRING( "Platsec violation, RF status SwP transition" ));
	
	if(hasCapability)
        {        
        if (IsSsmGracefulOffline())
            {
            //RF ON/OFF is implemented as a substate in Normal instead of SwP for graceful offline notification.
            //Hence the SwP RF OFF/RF ON is restricted for the request which has SSM SID. Only BtSap SwP transition is 
            //allowed to any client with appropriate capability.
            if (aMessage.SecureId() == KSsmSecureId || aSwp.Value() == ESsmBtSap )
                {
                //Allow SwP change only if request has SsmSecureId or the SwP request for BtSap
                isTransitionAllowed = EAllowed;
                }
            }
        else
            {
            isTransitionAllowed = EAllowed;
            }
        }	
	return isTransitionAllowed;
	}
/**
 * Performs further MultimediaDD policy check on clients connecting to the server.
 * 
 * Called at the start of the Sessions ServiceL routine
 */
void CMMCameraServerPolicyManager::ServiceHandlerL(const RMessage2& aMessage)
	{
	// If client is connecting to the server, make sure correct capabilities are set
	if (aMessage.Function() == ECamOpenCamera)
		{
		// Insert MMCapability into message buffer
		TOpenCamera parameters;
		TOpenCameraPckg openCamBuf(parameters);
		aMessage.ReadL(TInt(0), openCamBuf);

		parameters = openCamBuf();

		if (KMMCameraServerPolicyMultimediaDD.CheckPolicy(aMessage, __PLATSEC_DIAGNOSTIC_STRING ("CMMCameraServerPolicyManager::ServiceHandlerL KMMCameraServerPolicyMultimediaDD")))
			{
			parameters.iMMCapability = ETrue;
			}
		else
			{
			parameters.iMMCapability = EFalse;
			}

	    TOpenCameraPckg buf(parameters);

	    aMessage.WriteL(TInt(0), buf);	
		}

	// Add code here if necessary to check
	// clients ability to access particular
	// functions
	}
예제 #4
0
/**
  Process asynchronous requests.
*/
TInt DZeroCopyLoopbackChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
	{
	(void)a2;   // a2 not used in this example

	TInt r;

	switch(aReqNo)
		{
		case RZeroCopyLoopbackDriver::ESendData_ByZeroCopy:
			r = SendData(aStatus, (TInt)a1);
			break;

		case RZeroCopyLoopbackDriver::EReceiveData_ByZeroCopy:
			// Example Platform Security capability check which tests the
			// client for ECapability_None (which always passes)...
			if(iClient->HasCapability(ECapability_None,__PLATSEC_DIAGNOSTIC_STRING("Checked by zerocopy loopback")))
				r = ReceiveData(aStatus, (TInt*)a1);
			else
				r = KErrPermissionDenied;
			break;

		default:
			r = KErrNotSupported;
			break;
		}

	return r;
	}
/**
 * Enforces client connection policies.
 * 
 * Called by the server as the client connects
 */
void CMMCameraServerPolicyManager::OnConnectL(const RMessage2& aMessage)
	{
	// All users must have UserEnvironment capability
	if (!KMMCameraServerPolicyUserEnvironment.CheckPolicy(aMessage, __PLATSEC_DIAGNOSTIC_STRING("CMMCameraServerPolicyManager::OnConnectL KMMCameraServerPolicyUserEnvironment")))
		{
		User::Leave(KErrPermissionDenied);
		}
	}
예제 #6
0
void ExecHandler::PowerRequestWakeupEventNotification(TRequestStatus* aStatus)
	{
	if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Power::RequestWakeupEventNotification")))
		K::UnlockedPlatformSecurityPanic();
	NKern::ThreadEnterCS();
	PowerManager->RequestWakeupEventNotification(aStatus);
	NKern::ThreadLeaveCS();
	}	
예제 #7
0
void ExecHandler::PowerDisableWakeupEvents()
	{ 
	if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Power::DisableWakeupEvents")))
		K::UnlockedPlatformSecurityPanic();
	NKern::ThreadEnterCS();	
	PowerManager->DisableWakeupEvents();
	NKern::ThreadLeaveCS();
	}	
예제 #8
0
TInt ExecHandler::PowerDown()
	{
	if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Power::PowerDown")))
		K::UnlockedPlatformSecurityPanic();
	NKern::ThreadEnterCS();
	TInt r = PowerManager->PowerDown();
	NKern::ThreadLeaveCS();
	return r;
	}
예제 #9
0
TInt ExecHandler::PowerEnableWakeupEvents(TPowerState aState)
	{
	if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Power::EnableWakeupEvents")))
		K::UnlockedPlatformSecurityPanic();
	NKern::ThreadEnterCS();	
	TInt r = PowerManager->EnableWakeupEvents(aState);
	NKern::ThreadLeaveCS();
	return r;
	}	
예제 #10
0
/**
 Logical Channel - DoCreate(), called by framework after creating logical
 channel object as a part of the driver loading process. Driver should do
 the required validation like capabilities check, version check etc. It
 can do any required driver level initializations here.

 @param	aUnit
 		device unit number
 @param anInfo
 		device related information
 @param aVer
 		version number
 @return	KErrNone or standard error code
 */
TInt DExDriverLogicalChannel::DoCreate(TInt aUnit,
										const TDesC8* /*anInfo*/,
										const TVersion& aVer)
	{
	// Not using anInfo, so anInfo is commented in function arguments.
	// It can also be made void it to avoid compilation warnings by doing
	// (void)anInfo;

	// As a part of platform security guidelines, every driver needs to
	// enusure capability check. This check is to ensure that the client
	// accessing the driver has the required level of trust to perform any
	// operations on the device. Any client that does not have required
	// capability as expected by the driver is returned with no permission
	// error.Kernel API Kern::CurrentThreadHasCapability(),checks if the
	// current thread has the required capability (arg1) and displays the
	// diagnostic string in case of failure.
	//
	// Check if the client has level of trust to do serial comm related
	// operations.
	if (!Kern::CurrentThreadHasCapability(ECapabilityCommDD,
				__PLATSEC_DIAGNOSTIC_STRING("Checked by Tutorial Driver")))
		return KErrPermissionDenied;

	// Check if driver version matches with the version client is trying
	// to use. Kernel API, Kern::QueryVersionSupported() verifies if the
	// versions match, returns true if test version is less than current
	// version (arg2<arg1).
	//
	if (!Kern::QueryVersionSupported(iDevice->iVersion,aVer))
		return KErrNotSupported;

	// Store the LDD object pointer in PDD. This will enable PDD to access
	// and call the LDD member functions easily. In case of callbacks to
	// LDD, PDD can use this pointer.
	//
	Pdd()->iLdd=this;

	TInt r = Kern::MutexCreate(iSyncConfigDMutex, KExMutexName, KMutexOrdGeneral0);
 	if(r!= KErrNone)
 		return r;

	// Allocate buffers for Tx and Rx. Kern::Alloc allocates a block of
	// specified size and zero fills the memory block. On success, this returns
	// pointer to the allocated buffer, else returns NULL pointer
	//
	iTxBuffer = (TUint8*) Kern::Alloc(KTxBufferSize);
	if (!iTxBuffer)
		return KErrNoMemory;
	
	iRxBuffer = (TUint8*) Kern::Alloc(KRxBufferSize);
	if (!iRxBuffer)
		return KErrNoMemory;

	// return no error
    return KErrNone;
	}
예제 #11
0
LOCAL_C void TestCaps()
//
//	test format etc that require certain capabilities
//
	{
#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
	const char myDiagMsg[]="Capability Check Failure";
#endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
	r=RProcess().HasCapability(ECapabilityAllFiles, __PLATSEC_DIAGNOSTIC_STRING(myDiagMsg));
	test(!r);
	r=RProcess().HasCapability(ECapabilityTCB, __PLATSEC_DIAGNOSTIC_STRING(myDiagMsg));
	test(!r);
	r=RProcess().HasCapability(ECapabilityDiskAdmin, __PLATSEC_DIAGNOSTIC_STRING(myDiagMsg));
	test(!r);
	r=RProcess().HasCapability(ECapability_None, __PLATSEC_DIAGNOSTIC_STRING(myDiagMsg));
	test(r);

	driveBuf[0]=(TText)gDriveToTest;
	r=TheFs.SessionPath(temp);
	test_KErrNone(r);

	r=TheFs.CreatePrivatePath(gTheDriveNum);
	test_Value(r, r == KErrNone || r== KErrAlreadyExists);

	TBuf<18> tempPri;
	r=TheFs.PrivatePath(tempPri);
	test_KErrNone(r);
	theprivatepath = _L("?:");
	theprivatepath.Append(tempPri);

	TestNoCaps();

	TFileName thesessionpath;
	r=TheFs.SetSessionToPrivate(gTheDriveNum);
	test_KErrNone(r);
	r=TheFs.SessionPath(thesessionpath);
	test_KErrNone(r);
	
	test(thesessionpath == theprivatepath);

	}
예제 #12
0
TInt ExecHandler::AddEvent(const TRawEvent &aEvent)
//
// Add an event to the queue.
//
	{
	__KTRACE_OPT(KEVENT,Kern::Printf("Exec::AddEvent"));
	if(!Kern::CurrentThreadHasCapability(ECapabilitySwEvent,__PLATSEC_DIAGNOSTIC_STRING("Checked by UserSvr::AddEvent")))
		return KErrPermissionDenied;
	TRawEvent event;
	kumemget32(&event,&aEvent,sizeof(TRawEvent));
	TRawEvent::TType type = event.Type();
	if( (type==TRawEvent::ESwitchOff || type==TRawEvent::ECaseOpen || type==TRawEvent::ECaseClose || type==TRawEvent::ERestartSystem) && 
		!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by UserSvr::AddEvent")))
		return KErrPermissionDenied;
#ifdef BTRACE_TRAWEVENT		
	BTraceContext4(BTrace::ERawEvent, BTrace::EUserAddEvent ,(TUint32)type);
#endif
	NKern::ThreadEnterCS();	
	TInt r=Kern::AddEvent(event);
	NKern::ThreadLeaveCS();
	return r;
	}
예제 #13
0
/**
Called by the Device driver framework upon user request. 

@param aFunction	A number identifying the  message type
@param a1			A 32-bit Value passed by the user
@param a2			A 32-bit Value passed by the user

@return	KErrNone	If successful, otherwise one of the system wide error code
 */
TInt DExDriverLogicalChannel::Request(TInt aReqNo, TAny *a1, TAny *a2)
	{
	TInt r = KErrNone;
	
	KEXDEBUG(Kern::Printf("++DExDriverLogicalChannel::Request"));
	
	DThread* client;
	// Handle the synchronous requests. This is implementation specific,
	// however as a general practice, they are handled in DoControl().
	// Retrieve the current thread information using the kernel API. This
	// API gets the current Symbian OS thread, i.e reference to DThread
	// object.This thread information is required later in driver to
	// perform operations like data copy etc. across different threads.
	//
	client=&Kern::CurrentThread();


	// Check the capabilities of the thread before openning the handle.
	// As the handle sharing is allowed the client capabilities shall be checked
	// at the request level.
	// 
	if(!((client)->HasCapability(ECapabilityCommDD,
					__PLATSEC_DIAGNOSTIC_STRING("Checked by Tutorial Driver"))))
		{
		// If the required capability is not present for the user
        // thread to process this request, then deny the request.
        //
        return KErrPermissionDenied;
        }
        
	// Open kernel side refernce-counted object by calling DObject::Open()
	// DThread is derived from DObject. Opening this object increments the
	// reference count by one atomically.
	//
	((DObject*)client)->Open();
	
	r = DoControl(aReqNo, a1, a2);
	
	// Close the reference on client thread using the kernel API
	// Kern::SafeClose(). It swaps the kernel side reference counted object
	// to NULL value atomically and closes the object. This operation is
	// done in response to DObject::Close() in Logical Channel's destructor.
	//
	NKern::ThreadEnterCS();
	Kern::SafeClose((DObject*&)client,NULL);
	NKern::ThreadLeaveCS();
	
	// return result of above operations	
	return r;			
	}
예제 #14
0
TInt TFsFormatNext::Initialise(CFsRequest* aRequest)
//
//
//
	{
	if (!KCapFsFormatNext.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Format Next")))
		return KErrPermissionDenied;
	CFormatCB* format;
	format=GetFormatFromHandle(aRequest->Message().Int3(), aRequest->Session());
	if(!format)
		return(KErrBadHandle);	
	aRequest->SetDrive(&format->Drive());
	aRequest->SetScratchValue((TUint)format);
	return KErrNone;
	}
예제 #15
0
TInt TFsFormatOpen::Initialise(CFsRequest* aRequest)
//
//
//
	{
	TInt r;
	if (!KCapFsFormatOpen.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Format Open")))
		return KErrPermissionDenied;
	r=ParseNoWildSubstPtr0(aRequest,aRequest->Src());
	if (r!=KErrNone)
		return(r);
	if (aRequest->Src().NameOrExtPresent())
		return(KErrBadName);
	if (aRequest->SubstedDrive())
		return(KErrAccessDenied);
	return(r);
	}
예제 #16
0
TInt Wins::VariantHal(TInt aFunction, TAny* a1, TAny* /*a2*/)
	{
	TInt r=KErrNone;
	switch(aFunction)
		{
		case EVariantHalVariantInfo:
			{
			TVariantInfoV01Buf infoBuf;
			TVariantInfoV01& info=infoBuf();

//			info.iRomVersion=TVersion(KRomMajorVersionNumber,KRomMinorVersionNumber,KRomBuildVersionNumber);
			info.iMachineUniqueId=0;
			info.iLedCapabilities=0x0;
			info.iProcessorClockInKHz=iCpuSpeed ? iCpuSpeed*1000 : 1;
			info.iSpeedFactor=0;
			if (iUi)
				iUi->Info(info);

			Kern::InfoCopy(*(TDes8*)a1,infoBuf);
			break;
			}

		case EVariantHalCustomRestartReason:
			{
			//This will take value from c:\data\epoc.ini.
			TInt x = Property::GetInt("CustomRestartReason");    
			kumemput32(a1, &x, sizeof(TInt));
			}
			break;

		case EVariantHalCustomRestart:
			{
			if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EVariantHalCustomRestart")))
				return KErrPermissionDenied;
			//This will only shut down epoc as Custom Restart Reason is not supported on wins.
			Kern::Restart((TInt)a1);
			break;
			}

		default:
			r=KErrNotSupported;
			break;
		}
	return r;
	}
예제 #17
0
/**
  Second stage constructor called by the kernel's device driver framework.
  This is called in the context of the user thread (client) which requested the creation of a Logical Channel
  (E.g. through a call to RBusLogicalChannel::DoCreate)
  The thread is in a critical section.

  @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate
  @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate
  @param aVer The version argument supplied by the client to RBusLogicalChannel::DoCreate

  @return KErrNone if successful, otherwise one of the other system wide error codes.
*/
TInt DZeroCopyLoopbackChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer)
	{
	// Check Platform Security capabilities of client thread (if required).
	//
	// Here we handle the simple case where:
	// 1. The device driver can only have one client thread
	// 2. The security policy is the binary all-or-nothing policy.
	//    E.g. "If you have the right capability you can do anything with the driver
	//    and if you don't have the capability you can't do anything"
	// 
	// If only some functionality of the driver is restricted, then the security check should
	// go elsewhere. E.g. in DoRequest/DoControl. In that case Kern::CurrentThreadHasCapability
	// shouldn't be used because the 'current thread' isn't the client.
	//
	// In this example we do a check here for ECapability_None (which always passes)...
	if(!Kern::CurrentThreadHasCapability(ECapability_None,__PLATSEC_DIAGNOSTIC_STRING("Checked by zerocopy loopback")))
		return KErrPermissionDenied;

	// Check version
	if (!Kern::QueryVersionSupported(RZeroCopyLoopbackDriver::VersionRequired(),aVer))
		return KErrNotSupported;

	// Setup LDD for receiving client messages
	SetDfcQ(((DZeroCopyLoopbackPddFactory*)iPhysicalDevice)->iDfcQ);
	iMsgQ.Receive();

	// Associate DFCs with the same queue we set above to receive client messages on
	iSendDataDfc.SetDfcQ(iDfcQ);
	iReceiveDataDfc.SetDfcQ(iDfcQ);

	iPond = DCommsPond::New();
	if(!iPond)
		{
		return KErrNoMemory;
		}
	
	// Give PDD a pointer to this channel
	Pdd()->iLdd = this;

	// Done
	return KErrNone;
	}
예제 #18
0
/**
  Second stage constructor called by the kernel's device driver framework.
  This is called in the context of the user thread (client) which requested the creation
  of the Logical Channel (e.g. through a call to RBusLogicalChannel::DoCreate())
  The thread is in a critical section.

  @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate()
  @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate()
  @param aVer The version argument supplied by the client to RBusLogicalChannel::DoCreate()

  @return KErrNone if successful, otherwise one of the other system wide error codes.
*/
TInt DCrashDriverChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer)
    {
    if(!Kern::CurrentThreadHasCapability(ECapability_None,__PLATSEC_DIAGNOSTIC_STRING("Checked by crashdriver")))
        return KErrPermissionDenied;
     
    // Check version
    if (!Kern::QueryVersionSupported(RKernelCrashDrv::VersionRequired(),aVer))
        return KErrNotSupported;
    
    // Setup LDD for receiving client messages.
	TInt err = Kern::DynamicDfcQCreate(iDfcQ, 25, RKernelCrashDrv::Name());
	if(err != KErrNone)
		{
		Kern::Printf("Creating Dfc queue failed.");  	
		}
	SetDfcQ(iDfcQ);       
    iMsgQ.Receive();

    return KErrNone;    
    }
예제 #19
0
void ExecHandler::CaptureEventHook()
//
// Capture the event hook.
// Enter and leave with system unlocked.
//
	{
	__KTRACE_OPT(KEVENT,Kern::Printf("Exec::CaptureEventHook"));

	if(TheCurrentThread->iOwningProcess!=K::TheWindowServerProcess)
		{
		NKern::LockSystem();
		K::ProcessIsolationFailure(__PLATSEC_DIAGNOSTIC_STRING("Checked by UserSvr::CaptureEventHook"));
		}
	NKern::FMWait(&K::EventQueueMutex);
	if (!K::EventThread)
		K::EventThread=TheCurrentThread;
	else
		EventQueuePanic(EEventAlreadyCaptured);
	NKern::FMSignal(&K::EventQueueMutex);
	}
TInt DKeyboardNE1_TB::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
	{
	TInt r=KErrNone;
	__KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardNE1_TB::HalFunction %d", aFunction));
	switch(aFunction)
		{
		case EKeyboardHalKeyboardInfo:
			{
			TPckgBuf<TKeyboardInfoV01> kPckg;
			KeyboardInfo(kPckg());
			Kern::InfoCopy(*(TDes8*)a1,kPckg);
			break;
			}
		case EKeyboardHalSetKeyboardState:
			{
			if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EKeyboardHalSetKeyboardState")))
				return KErrPermissionDenied;
			if ((TBool)a1)
				{
				TThreadMessage& m=Kern::Message();
				m.iValue = ETrue;
				m.SendReceive(&iMsgQ);		// send a message and block Client thread until keyboard has been powered up
				}
			else
				{
				TThreadMessage& m=Kern::Message();
				m.iValue = EFalse;
				m.SendReceive(&iMsgQ);		// send a message and block Client thread until keyboard has been powered down
				}
			}
			break;
		case EKeyboardHalKeyboardState:
			kumemput32(a1, &iKeyboardOn, sizeof(TBool));
			break;
		default:
			r=KErrNotSupported;
			break;
		}
	return r;
	}
예제 #21
0
TInt DChannelComm::DoCreate(TInt aUnit, const TDesC8* /*aInfo*/, const TVersion &aVer)
	{
	if(!Kern::CurrentThreadHasCapability(ECapabilityCommDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by ECOMM.LDD (Comm Driver)")))
   		return KErrPermissionDenied;		
	if (!Kern::QueryVersionSupported(TVersion(KCommsMajorVersionNumber,KCommsMinorVersionNumber,KCommsBuildVersionNumber),aVer))
		return KErrNotSupported;

	// set up the correct DFC queue
	SetDfcQ(((DComm*)iPdd)->DfcQ(aUnit));
	iRxCompleteDfc.SetDfcQ(iDfcQ);
	iTxCompleteDfc.SetDfcQ(iDfcQ);
	iRxDataAvailableDfc.SetDfcQ(iDfcQ);
	iSigNotifyDfc.SetDfcQ(iDfcQ);
	iTurnaroundDfc.SetDfcQ(iDfcQ);
	iMsgQ.Receive();

	((DComm *)iPdd)->iLdd = this;

	//setup the initial port configuration
	PddConfigure(iConfig);
	
	return KErrNone;
	}
예제 #22
0
/**
	LDD second stage constructor
*/
TInt DDisplayLdd::DoCreate(TInt aUnit, const TDesC8* /* anInfo*/, const TVersion& aVer)
	{ 
	
	__DEBUG_PRINT("DDisplayLdd::DoCreate()\n"); 

	if(    !Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,      __PLATSEC_DIAGNOSTIC_STRING("Checked by DISPLAY.LDD (GCE Driver)") )
		|| !Kern::CurrentThreadHasCapability(ECapabilityReadDeviceData, __PLATSEC_DIAGNOSTIC_STRING("Checked by DISPLAY.LDD (GCE Driver)") )
		|| !Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by DISPLAY.LDD (GCE Driver)") )
		|| !Kern::CurrentThreadHasCapability(ECapabilityProtServ,       __PLATSEC_DIAGNOSTIC_STRING("Checked by DISPLAY.LDD (GCE Driver)") ) )
		{
		return KErrPermissionDenied;
		}
		  
	// Check that the display driver version specified by the client is compatible.
	if (!Kern::QueryVersionSupported(RDisplayChannel::VersionRequired(),aVer))
		{
		return(KErrNotSupported);		
		}
				
	// Check that a channel hasn't already been opened on this unit.
	TInt r=((DDisplayLddFactory*)iDevice)->SetUnitOpen(aUnit,ETrue); // Try to update 'units open mask' in the LDD factory.
	if (r!=KErrNone)
		return r;
	iUnit=aUnit;

 	Pdd()->iLdd	= this;
 	
 	r		= Pdd()->CreateChannelSetup(aUnit); 	
 	if ( r!= KErrNone)
 		{
 		return r; 		
 		}
 
     // set up user buffer nodes
    for (TInt node = 0; node < KDisplayUBMax; node++)
    	{
        iUserBuffer[node].iType 	= EBufferTypeUser;
        iUserBuffer[node].iBufferId = (node + 1);
        iUserBuffer[node].iFree 	= ETrue;
        iUserBuffer[node].iState 	= EBufferFree;
        iUserBuffer[node].iAddress  = 0;
        iUserBuffer[node].iSize  	= 0;
        iUserBuffer[node].iHandle  	= 0;
        iUserBuffer[node].iChunk  	= 0;
        iUserBuffer[node].iOffset 	= 0;
        iUserBuffer[node].iPendingRequest = 0;
    	}

    //Initialise pending queue for asynchronous requests and queue of TClientRequests
    for(TInt k = 0; k < KPendingReqArraySize; k++) 
    	{
    	
    	iPendingIndex[k]=0;
    	
		for(TInt i = 0; i < KMaxQueuedRequests; i++)
			{
			iPendingReq[k][i].iTClientReq   = 0;
			iPendingReq[k][i].iOwningThread = 0;
			
			
			r = Kern::CreateClientRequest(iClientRequest[k][i]);
			if (r != KErrNone)
				{
				return r;      	
				}
			}	
    	} 
    
    r = Kern::MutexCreate(iClientRequestMutex, KClientRequestMutex, KMutexOrder);	
	if (r != KErrNone)
		{
		return r;
		}	
    
          
    Pdd()->SetGceMode();	
	SetDfcQ(Pdd()->DfcQ(aUnit));	   
    iMsgQ.Receive();
    
    return KErrNone;		
}
예제 #23
0
void ExecHandler::PowerCancelWakeupEventNotification()
	{ 
	if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Power::CancelWakeupEventNotification")))
		K::UnlockedPlatformSecurityPanic();
	PowerManager->CancelWakeupEventNotification();
	}	
예제 #24
0
/** 
 Handle Synchronous Requests. This is called from HandleMsg() to process
 synchronous requests, that perform the action quickly and returns.
 Handling these requests is implementation specific. However, if it needs
 any hardware operation, then PDD function can be invoked from here.
 
 @param 	aFunction
 		  	Request number
 @param 	a1
 			parameter1 passed by user for the request
 @param 	a2
 			parameter2 passed by user for the request
 			
 @return	KErrNone or standard error code
 */	
TInt DExDriverLogicalChannel::DoControl(TInt aFunction, TAny* a1) // a2 is not being used
	{
	KEXDEBUG(Kern::Printf("++DExDriverLogicalChannel::DoControl"));

	TInt r;
	
	// Switch over the request type. Typically the requests that are
	// passed here will be RExdDriver::TControl enumerated requests
	// sent by the user in user side DoControl() request
	//
	switch(aFunction)
		{
		// User request to read the channel capabilities of Uart driver
		//
		case RExDriverChannel::EControlCaps:
			// Check if the client thread has ECapabilityCommDD capability
			// for the driver to process this request. Driver can enforce
			// more capability checks (other than those checked during channel
			// creation), for individual requests.
			//
			// Any API specific capability can be checked this way. Capability
			// that has already been checked while opening need not be checked
			// again here.
			//
			if(iClient->HasCapability(ECapabilityCommDD,
					__PLATSEC_DIAGNOSTIC_STRING("Checked by Tutorial Driver")))
				{
				// Call Caps() to retrieve capabilities to a1
				r = Caps((TDes8*)a1);
				}
            else
            	{
            	// If the required capability is not present for the user
            	// thread to process this request, then deny the request.
            	//
            	r=KErrPermissionDenied;
            	}
			break;
			
		// User request to configure the device (uart)
		//
		case RExDriverChannel::EControlSetConfig:
			// Call SetConfig function by passing the first argument
			r = SetConfig((const TDesC8*)a1);
			break;
			
		// User request to enable or disable the device's internal loopback mode
		//
		case RExDriverChannel::EControlSetIntLoopback:
			// Call SetIntLoopback function by passing the first argument
			r = SetIntLoopback((const TInt*)a1);
			break;
			
		// User request to get the handle for Tx chunk. This will actually
		// create and return the handle created.	
		//
		case RExDriverChannel::EGetTxChunkHandle:
			// This is a synchronous request and a1 will hold the chunk 
			// handle value (>0 if success) after return 
			//
			r = GetTxChunkHandle((TInt*)a1);
			break;	
				
		// User request to get the handle for Rx chunk. This will actually
		// create and return the handle created.	
		//
		case RExDriverChannel::EGetRxChunkHandle:
			// This is a synchronous request and a1 will hold the chunk 
			// handle value (>0 if success) after return 
			//						
			r = GetRxChunkHandle((TInt*)a1);
			break;
			
		// User request to pass the handle for Tx chunk.
		// This shared chunk is created by other driver (Channel) and passed here.
		case RExDriverChannel::EPassTxChunkHandle:
			// This is a synchronous request and a1 will hold the chunk 
			// handle value (KErrNone if success) after return 
			//						
			r = PassTxChunkHandle((TInt*)a1);
			break;
			
		// User request to pass the handle for Rx chunk.
		// This shared chunk is created by other driver (Channel) and passed here.
		case RExDriverChannel::EPassRxChunkHandle:
			// This is a synchronous request and a1 will hold the chunk 
			// handle value (KErrNone if success) after return 
			//						
			r = PassRxChunkHandle((TInt*)a1);
			break;
						
		default:
			// Unknown request and therefore not supported
			//
			r = KErrNotSupported;			
	}
	
	return r;
	}
예제 #25
0
/**
 Logical Channel - DoCreate(), called by framework after creating logical
 channel object as a part of the driver loading process. Driver should do
 the required validation like capabilities check, version check etc. It
 associates the DFC queue which it shall use to queue the requests. It
 can do any required driver level initializations here.
   
 @param	aUnit
 		device unit number
 @param anInfo
 		device related information
 @param aVer
 		version number
 @return	KErrNone or standard error code
 */
TInt DExDriverLogicalChannel::DoCreate(TInt aUnit,
										const TDesC8* /*anInfo*/,
										const TVersion& aVer)
	{


	// Not using anInfo, so anInfo is commented in function arguments.
	// It can also be made void it to avoid compilation warnings by doing
	// (void)anInfo;
	//
	// As a part of platform security guidelines, every driver needs to
	// enusure capability check. This check is to ensure that the client
	// accessing the driver has the required level of trust to perform any
	// operations on the device. Any client that does not have required
	// capability as expected by the driver is returned with no permission
	// error.Kernel API Kern::CurrentThreadHasCapability(),checks if the
	// current thread has the required capability (arg1) and displays the
	// diagnostic string in case of failure.
	//
	// Check if the client has level of trust to do serial comm related
	// operations.
	if (!Kern::CurrentThreadHasCapability(ECapabilityCommDD,
				__PLATSEC_DIAGNOSTIC_STRING("Checked by Tutorial Driver")))
		return KErrPermissionDenied;

	// Check if driver version matches with the version client is trying
	// to use. Kernel API, Kern::QueryVersionSupported() verifies if the
	// versions match, returns true if test version is less than current
	// version (arg2<arg1).
	//
	if (!Kern::QueryVersionSupported(iDevice->iVersion,aVer))
		return KErrNotSupported;
	

	// Store the LDD object pointer in PDD. This will enable PDD to access
	// and call the LDD member functions easily. In case of callbacks to
	// LDD, PDD can use this pointer.
	//
	Pdd()->iLdd=this;
	// Logical channel based driver has a DFC created for itself. A dedicated
	// DFC can be created for the driver, instead of using default kernel DFC
	// thread 0. PDD implements DFCQ function and returns the DFCQ created
	// by PDD. All synchronous and asynchronous messages and events for this 
	// driver will be queued to this queue.
	// 
	// Here, LDD leaves it to PDD to associate a context,(dfcq+kernel thread)
	// with a hardware unit, so that requests on different channels (units)
	// execute in different contexts.
	//
	// SetDfcQ() initializes the message queue used by LDD with the 
	// DFC(TDynamicDfcQue object) returned by Pdd()->DfcQ().
	//
	SetDfcQ(Pdd()->DfcQ(aUnit));
        
	// Set the message queue to start receiving the messages.
	// TMessageQue::Receive() will request driver to receive next message
	// (sent by client) in the queue. It makes the queue as ready and also 
	// activates the DFC when the message is present in queue.
	//
    iMsgQ.Receive();
    
    Pdd()->SetChannelOpened(aUnit);
	// return no error
	//
    return KErrNone;
	}
예제 #26
0
/**
	Create channel.

@param aVer The version number required.
@return KErrNone on success, KErrNotSupported if the device doesn't support defragmentation.
*/
TInt DDefragChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
    {
	// Check the client has ECapabilityPowerMgmt capability.
	if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt, __PLATSEC_DIAGNOSTIC_STRING("Checked by DDefragChannel")))
		{
		return KErrPermissionDenied;
		}
	TInt pageSize;
	TInt r = Kern::HalFunction(EHalGroupKernel, EKernelHalPageSizeInBytes, &pageSize, 0);
	if (r != KErrNone)
		{
		TRACE(Kern::Printf("ERROR - Unable to determine page size"));
		return r;
		}
	TUint32 pageMask = pageSize;
	TUint i = 0;
	for (; i < 32; i++)
		{
		if (pageMask & 1)
			{
			if (pageMask & ~1u)
				{
				TRACE(Kern::Printf("ERROR - page size not a power of 2"));
				return KErrNotSupported;
				}
			iPageShift = i;
			break;
			}
		pageMask >>= 1;
		}

	// Check the client is a supported version.
    if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
		{
    	return KErrNotSupported;
		}

	// Check this system has more than one RAM zone defined.
	// A real driver shouldn't need to do this as any driver that uses defrag should 
	// only be loaded on devices that support it.
	TInt ret = FindLowestPrefZone();
	if (ret != KErrNone)
		{// Only one zone so can't move pages anywhere or empty a zone
		return KErrNotSupported;
		}

	// Create a semaphore to protect defrag invocation.  OK to just use one name as
	// the semaphore is not global so it's name doesn't need to be unique.
	ret = Kern::SemaphoreCreate(iDefragSemaphore, _L("DefragRefSem"), 1);
	if (ret != KErrNone)
		{
		return ret;
		}

	// Create a client request for completing dfc defrag requests.
	ret = Kern::CreateClientRequest(iCompleteReq);
	if (ret != KErrNone)
		{
		iDefragSemaphore->Close(NULL);
		return ret;
		}

	// Setup a DFC to be invoked when a defrag operation completes.
	iDefragCompleteDfc.SetDfcQ(iDfcQ);
	iDefragDfcFree = ETrue;

	return KErrNone;
	}