usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/src/CUsbMsClassController.cpp
branchRCL_3
changeset 16 012cc2ee6408
parent 15 f92a4f87e424
equal deleted inserted replaced
15:f92a4f87e424 16:012cc2ee6408
     1 /*
     1 /*
     2 * Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 * Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
    26 #include <barsread.h>
    26 #include <barsread.h>
    27 #include <usb_std.h>
    27 #include <usb_std.h>
    28 #include <cusbclasscontrollerplugin.h>
    28 #include <cusbclasscontrollerplugin.h>
    29 #include <usbms.rsg>
    29 #include <usbms.rsg>
    30 #include "CUsbMsClassController.h"
    30 #include "CUsbMsClassController.h"
    31 #include "OstTraceDefinitions.h"
    31 #include <usb/usblogger.h>
    32 #ifdef OST_TRACE_COMPILER_IN_USE
    32  
    33 #include "CUsbMsClassControllerTraces.h"
    33 #ifdef __FLOG_ACTIVE
       
    34 _LIT8(KLogComponent, "MSCC");
    34 #endif
    35 #endif
    35 
    36 
       
    37 // Panic category 
    36 #ifdef _DEBUG
    38 #ifdef _DEBUG
    37 // Panic category 
       
    38 _LIT( KMsCcPanicCategory, "UsbMsCc" );
    39 _LIT( KMsCcPanicCategory, "UsbMsCc" );
    39 #endif
    40 #endif
    40 
    41 
    41 /**
    42 /**
    42  Panic codes for the USB mass storage Class Controller.
    43  Panic codes for the USB mass storage Class Controller.
    55  @return	A new CUsbMsClassController object
    56  @return	A new CUsbMsClassController object
    56  */
    57  */
    57 CUsbMsClassController* CUsbMsClassController::NewL(
    58 CUsbMsClassController* CUsbMsClassController::NewL(
    58 	MUsbClassControllerNotify& aOwner)
    59 	MUsbClassControllerNotify& aOwner)
    59 	{
    60 	{
    60 	OstTraceFunctionEntry0( CUSBMSCLASSCONTROLLER_NEWL_ENTRY );
    61 	LOG_STATIC_FUNC_ENTRY
       
    62 
    61 	CUsbMsClassController* r = new (ELeave) CUsbMsClassController(aOwner);
    63 	CUsbMsClassController* r = new (ELeave) CUsbMsClassController(aOwner);
    62 	CleanupStack::PushL(r);
    64 	CleanupStack::PushL(r);
    63 	r->ConstructL();
    65 	r->ConstructL();
    64 	CleanupStack::Pop();
    66 	CleanupStack::Pop();
    65 	OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_NEWL_EXIT );
       
    66 	return r;
    67 	return r;
    67 	}
    68 	}
    68 
    69 
    69 /**
    70 /**
    70  Destructor
    71  Destructor
    71  */
    72  */
    72 CUsbMsClassController::~CUsbMsClassController()
    73 CUsbMsClassController::~CUsbMsClassController()
    73 	{
    74 	{
    74 	OstTraceFunctionEntry0( CUSBMSCLASSCONTROLLER_CUSBMSCLASSCONTROLLER_DES_ENTRY );
       
    75 	Cancel();
    75 	Cancel();
    76 	OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_CUSBMSCLASSCONTROLLER_DES_EXIT );
       
    77 	}
    76 	}
    78 
    77 
    79 /**
    78 /**
    80  Constructor.
    79  Constructor.
    81  
    80  
    83  */
    82  */
    84 CUsbMsClassController::CUsbMsClassController(
    83 CUsbMsClassController::CUsbMsClassController(
    85 	MUsbClassControllerNotify& aOwner)
    84 	MUsbClassControllerNotify& aOwner)
    86 	: CUsbClassControllerPlugIn(aOwner, KMsStartupPriority)	
    85 	: CUsbClassControllerPlugIn(aOwner, KMsStartupPriority)	
    87 	{
    86 	{
    88 	OstTraceFunctionEntry0( CUSBMSCLASSCONTROLLER_CUSBMSCLASSCONTROLLER_CONS_ENTRY );
       
    89 	// Intentionally left blank
    87 	// Intentionally left blank
    90 	OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_CUSBMSCLASSCONTROLLER_CONS_EXIT );
       
    91 	}
    88 	}
    92 
    89 
    93 /**
    90 /**
    94  2nd Phase Construction.
    91  2nd Phase Construction.
    95  */
    92  */
    96 void CUsbMsClassController::ConstructL()
    93 void CUsbMsClassController::ConstructL()
    97 	{
    94 	{
    98 	OstTraceFunctionEntry0( CUSBMSCLASSCONTROLLER_CONSTRUCT_ENTRY );
    95 	LOG_FUNC
       
    96 
    99 	ReadMassStorageConfigL();
    97 	ReadMassStorageConfigL();
   100 	OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_CONSTRUCT_EXIT );
       
   101 	}
    98 	}
   102 
    99 
   103 /**
   100 /**
   104  Called by UsbMan when it wants to start the mass storage class. 
   101  Called by UsbMan when it wants to start the mass storage class. 
   105  
   102  
   106  @param aStatus The caller's request status, filled in with an error code
   103  @param aStatus The caller's request status, filled in with an error code
   107  */
   104  */
   108 void CUsbMsClassController::Start(TRequestStatus& aStatus)
   105 void CUsbMsClassController::Start(TRequestStatus& aStatus)
   109 	{
   106 	{
   110 	OstTraceFunctionEntry0( CUSBMSCLASSCONTROLLER_START_ENTRY );
   107 	LOG_FUNC
   111 	
   108 	
   112 	// The service state should always be idle when this function is called 
   109 	// The service state should always be idle when this function is called 
   113 	// (guaranteed by CUsbSession).
   110 	// (guaranteed by CUsbSession).
   114 	
   111 	__ASSERT_DEBUG( iState == EUsbServiceIdle, _USB_PANIC(KMsCcPanicCategory, EBadApiCall) );
   115 	if (iState != EUsbServiceIdle)
       
   116 		{
       
   117 		OstTrace1( TRACE_FATAL, CUSBMSCLASSCONTROLLER_START, "CUsbMsClassController::Star;iState=%d", (TInt)iState );
       
   118 		__ASSERT_DEBUG( EFalse, User::Panic(KMsCcPanicCategory, EBadApiCall) );
       
   119 		}
       
   120 
   112 
   121 	TRequestStatus* reportStatus = &aStatus;
   113 	TRequestStatus* reportStatus = &aStatus;
   122 
   114 
   123 	iState = EUsbServiceStarting;
   115 	iState = EUsbServiceStarting;
   124 
   116 
   127 
   119 
   128 	if (err != KErrNone)
   120 	if (err != KErrNone)
   129 		{
   121 		{
   130 		iState = EUsbServiceIdle;
   122 		iState = EUsbServiceIdle;
   131 		User::RequestComplete(reportStatus, err);
   123 		User::RequestComplete(reportStatus, err);
   132 		OstTrace0( TRACE_NORMAL, CUSBMSCLASSCONTROLLER_START_DUP1, 
   124 		LOGTEXT(_L8("Failed to connect to mass storage file server"));
   133 				"CUsbMsClassController::Start;Failed to connect to mass storage file server" );
       
   134 		OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_START_EXIT );
       
   135 		return;
   125 		return;
   136 		}
   126 		}
   137 
   127 
   138 	// Start mass storage device
   128 	// Start mass storage device
   139 	err = iUsbMs.Start(iMsConfig);
   129 	err = iUsbMs.Start(iMsConfig);
   140 
   130 
   141 	if (err != KErrNone)
   131 	if (err != KErrNone)
   142 		{
   132 		{
   143 		iState = EUsbServiceIdle;
   133 		iState = EUsbServiceIdle;
       
   134 		
   144 		// Connection was created successfully in last step
   135 		// Connection was created successfully in last step
   145 		// Get it closed since failed to start device.
   136 		// Get it closed since failed to start device.
   146 		iUsbMs.Close();
   137 		iUsbMs.Close();
       
   138 		
   147 		User::RequestComplete(reportStatus, err);
   139 		User::RequestComplete(reportStatus, err);
   148 		OstTrace0( TRACE_NORMAL, CUSBMSCLASSCONTROLLER_START_DUP2, 
   140 		LOGTEXT(_L8("Failed to start mass storage device"));
   149 						"CUsbMsClassController::Start;Failed to start mass storage device" );
       
   150 		OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_START_EXIT_DUP1 );
       
   151 		return;
   141 		return;
   152 		}
   142 		}
   153 
   143 
   154 	iState = EUsbServiceStarted;
   144 	iState = EUsbServiceStarted;
       
   145 
   155 	User::RequestComplete(reportStatus, KErrNone);
   146 	User::RequestComplete(reportStatus, KErrNone);
   156 	OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_START_EXIT_DUP2 );
       
   157 	}
   147 	}
   158 
   148 
   159 /**
   149 /**
   160  Called by UsbMan when it wants to stop the USB ACM class.
   150  Called by UsbMan when it wants to stop the USB ACM class.
   161  
   151  
   162  @param aStatus KErrNone on success or a system wide error code
   152  @param aStatus KErrNone on success or a system wide error code
   163  */
   153  */
   164 void CUsbMsClassController::Stop(TRequestStatus& aStatus)
   154 void CUsbMsClassController::Stop(TRequestStatus& aStatus)
   165 	{
   155 	{
   166 	OstTraceFunctionEntry0( CUSBMSCLASSCONTROLLER_STOP_ENTRY );
   156 	LOG_FUNC
   167 	
   157 	
   168 	// The service state should always be started when this function is called
   158 	// The service state should always be started when this function is called
   169 	// (guaranteed by CUsbSession)
   159 	// (guaranteed by CUsbSession)
   170 	if (iState != EUsbServiceStarted)
   160 	__ASSERT_DEBUG( iState == EUsbServiceStarted, _USB_PANIC(KMsCcPanicCategory, EBadApiCall) );
   171 		{
       
   172 		OstTrace1( TRACE_FATAL, CUSBMSCLASSCONTROLLER_STOP, "CUsbMsClassController::Stop;iState=%d", (TInt)iState );
       
   173 		__ASSERT_DEBUG( EFalse, User::Panic(KMsCcPanicCategory, EBadApiCall) );
       
   174 		}
       
   175 
   161 
   176 	TRequestStatus* reportStatus = &aStatus;
   162 	TRequestStatus* reportStatus = &aStatus;
       
   163 	
   177 	TInt err = iUsbMs.Stop();
   164 	TInt err = iUsbMs.Stop();
   178 	
   165 	
   179 	if (err != KErrNone)
   166 	if (err != KErrNone)
   180 		{
   167 		{
   181 		iState = EUsbServiceStarted;
   168 		iState = EUsbServiceStarted;
   182 		User::RequestComplete(reportStatus, err);
   169 		User::RequestComplete(reportStatus, err);
   183 		OstTrace0( TRACE_NORMAL, CUSBMSCLASSCONTROLLER_STOP_DUP1, 
   170 		LOGTEXT(_L8("Failed to stop mass storage device"));
   184 						"CUsbMsClassController::Start;Failed to stop mass storage device" );
       
   185 		OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_STOP_EXIT );
       
   186 		return;
   171 		return;
   187 		}	
   172 		}	
   188 
   173 
   189 	iUsbMs.Close();
   174 	iUsbMs.Close();
       
   175 
   190 	User::RequestComplete(reportStatus, KErrNone);
   176 	User::RequestComplete(reportStatus, KErrNone);
   191 	OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_START_STOP_DUP1 );
       
   192 	}
   177 	}
   193 
   178 
   194 /**
   179 /**
   195  Gets information about the descriptor which this class provides. Never called
   180  Gets information about the descriptor which this class provides. Never called
   196  by usbMan.
   181  by usbMan.
   197  
   182  
   198  @param aDescriptorInfo Descriptor info structure filled in by this function
   183  @param aDescriptorInfo Descriptor info structure filled in by this function
   199  */
   184  */
   200 void CUsbMsClassController::GetDescriptorInfo(TUsbDescriptor& /*aDescriptorInfo*/) const
   185 void CUsbMsClassController::GetDescriptorInfo(TUsbDescriptor& /*aDescriptorInfo*/) const
   201 	{
   186 	{
   202 	OstTraceFunctionEntry0( CUSBMSCLASSCONTROLLER_GETDESCRIPTORINFO_ENTRY );
   187 	__ASSERT_DEBUG( EFalse, _USB_PANIC(KMsCcPanicCategory, EUnusedFunction));
   203 	OstTrace1( TRACE_FATAL, CUSBMSCLASSCONTROLLER_GETDESCRIPTORINFO, 
       
   204 			"CUsbMsClassController::GetDescriptorInfo;panic line=%d", (TInt)__LINE__ );
       
   205 	__ASSERT_DEBUG( EFalse, User::Panic(KMsCcPanicCategory, EUnusedFunction) );
       
   206 	OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_GETDESCRIPTORINFO_EXIT );
       
   207 	}
   188 	}
   208 
   189 
   209 /**
   190 /**
   210  Standard active object RunL. Never called because this class has no
   191  Standard active object RunL. Never called because this class has no
   211  asynchronous requests.
   192  asynchronous requests.
   212  */
   193  */
   213 void CUsbMsClassController::RunL()
   194 void CUsbMsClassController::RunL()
   214 	{
   195 	{
   215 	OstTraceFunctionEntry0( CUSBMSCLASSCONTROLLER_RUNL_ENTRY );
   196 	__ASSERT_DEBUG( EFalse, _USB_PANIC(KMsCcPanicCategory, EUnusedFunction) );
   216 	OstTrace1( TRACE_FATAL, CUSBMSCLASSCONTROLLER_RUNL, 
       
   217 			"CUsbMsClassController::RunL;panic line=%d", (TInt)__LINE__ );
       
   218 	__ASSERT_DEBUG( EFalse, User::Panic(KMsCcPanicCategory, EUnusedFunction) );
       
   219 	OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_RUNL_EXIT );
       
   220 	}
   197 	}
   221 
   198 
   222 /**
   199 /**
   223  Standard active object cancellation function. Never called because this
   200  Standard active object cancellation function. Never called because this
   224  class has no asynchronous requests.
   201  class has no asynchronous requests.
   225  */
   202  */
   226 void CUsbMsClassController::DoCancel()
   203 void CUsbMsClassController::DoCancel()
   227 	{
   204 	{
   228 	OstTraceFunctionEntry0( CUSBMSCLASSCONTROLLER_DOCANCEL_ENTRY );
   205 	__ASSERT_DEBUG( EFalse, _USB_PANIC(KMsCcPanicCategory, EUnusedFunction) );
   229 	OstTrace1( TRACE_FATAL, CUSBMSCLASSCONTROLLER_DOCANCEL, 
       
   230 			"CUsbMsClassController::DoCancel;panic line=%d", (TInt)__LINE__ );
       
   231 	__ASSERT_DEBUG( EFalse, User::Panic(KMsCcPanicCategory, EUnusedFunction) );
       
   232 	OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_DOCANCEL_EXIT );
       
   233 	}
   206 	}
   234 
   207 
   235 /**
   208 /**
   236  Standard active object error function. Never called because this class has
   209  Standard active object error function. Never called because this class has
   237  no asynchronous requests, and hence its RunL is never called.
   210  no asynchronous requests, and hence its RunL is never called.
   239  @param aError The error code (unused)
   212  @param aError The error code (unused)
   240  @return Always KErrNone to avoid an active scheduler panic
   213  @return Always KErrNone to avoid an active scheduler panic
   241  */
   214  */
   242 TInt CUsbMsClassController::RunError(TInt /*aError*/)
   215 TInt CUsbMsClassController::RunError(TInt /*aError*/)
   243 	{
   216 	{
   244 	OstTraceFunctionEntry0( CUSBMSCLASSCONTROLLER_RUNERROR_ENTRY );
   217 	__ASSERT_DEBUG( EFalse, _USB_PANIC(KMsCcPanicCategory, EUnusedFunction) );
   245 	OstTrace1( TRACE_FATAL, CUSBMSCLASSCONTROLLER_RUNERROR, 
       
   246 			"CUsbMsClassController::RunError;panic line=%d", (TInt)__LINE__ );
       
   247 	__ASSERT_DEBUG( EFalse, User::Panic(KMsCcPanicCategory, EUnusedFunction) );
       
   248 	OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_RUNERROR_EXIT );
       
   249 	return KErrNone;
   218 	return KErrNone;
   250 	}
   219 	}
   251 
   220 
   252 /**
   221 /**
   253  Read mass storage configuration info from the resource file
   222  Read mass storage configuration info from the resource file
   254  */
   223  */
   255 void CUsbMsClassController::ReadMassStorageConfigL()
   224 void CUsbMsClassController::ReadMassStorageConfigL()
   256 	{
   225 	{
   257 	OstTraceFunctionEntry0( CUSBMSCLASSCONTROLLER_READMASSSTORAGECONFIGL_ENTRY );
   226 	LOG_FUNC
   258 
   227 
   259 	// Try to connect to file server
   228 	// Try to connect to file server
   260 	RFs		fs;
   229 	RFs fs;
   261 	TInt	fserr = fs.Connect();
   230 	LEAVEIFERRORL(fs.Connect());
   262 	
       
   263 	if (fserr < 0)
       
   264 		{
       
   265 		OstTrace1( TRACE_FATAL, CUSBMSCLASSCONTROLLER_READMASSSTORAGECONFIGL, 
       
   266 				"CUsbMsClassController::ReadMassStorageConfigL;leave err = %d", fserr );
       
   267 		User::Leave(fserr);
       
   268 		}
       
   269 	CleanupClosePushL(fs);
   231 	CleanupClosePushL(fs);
   270 
   232 
   271 	RResourceFile resource;
   233 	RResourceFile resource;
   272 	TRAPD(err, resource.OpenL(fs, KUsbMsResource));
   234 	TRAPD(err, resource.OpenL(fs, KUsbMsResource));
   273 	OstTrace1( TRACE_NORMAL, CUSBMSCLASSCONTROLLER_READMASSSTORAGECONFIGL_DUP1, 
   235 	LOGTEXT2(_L8("Opened resource file with error %d"), err);
   274 				"CUsbMsClassController::ReadMassStorageConfigL;Opened resource file with error %d", err );
       
   275 
   236 
   276 	if (err != KErrNone)
   237 	if (err != KErrNone)
   277 		{
   238 		{
   278 		OstTrace0( TRACE_NORMAL, CUSBMSCLASSCONTROLLER_READMASSSTORAGECONFIGL_DUP2, 
   239 		LOGTEXT(_L8("Unable to open resource file"));
   279 					"CUsbMsClassController::ReadMassStorageConfigL;Unable to open resource file" );
       
   280 		CleanupStack::PopAndDestroy(&fs);
   240 		CleanupStack::PopAndDestroy(&fs);
   281 		OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_READMASSSTORAGECONFIGL_EXIT );
       
   282 		return;
   241 		return;
   283 		}
   242 		}
   284 
   243 
   285 	CleanupClosePushL(resource);
   244 	CleanupClosePushL(resource);
   286 
   245 
   288 
   247 
   289 	HBufC8* msConfigBuf = 0;
   248 	HBufC8* msConfigBuf = 0;
   290 	TRAPD(ret, msConfigBuf = resource.AllocReadL(USBMS_CONFIG));
   249 	TRAPD(ret, msConfigBuf = resource.AllocReadL(USBMS_CONFIG));
   291 	if (ret != KErrNone)
   250 	if (ret != KErrNone)
   292 		{
   251 		{
   293 		OstTrace0( TRACE_NORMAL, CUSBMSCLASSCONTROLLER_READMASSSTORAGECONFIGL_DUP3, 
   252 		LOGTEXT(_L8("Failed to open mass storage configuration file"));
   294 					"CUsbMsClassController::ReadMassStorageConfigL;Failed to open mass storage configuration file" );
       
   295 		CleanupStack::PopAndDestroy(2, &fs); 
   253 		CleanupStack::PopAndDestroy(2, &fs); 
   296 		OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_READMASSSTORAGECONFIGL_EXIT_DUP1 );
       
   297 		return;
   254 		return;
   298 		}
   255 		}
   299 	CleanupStack::PushL(msConfigBuf);
   256 	CleanupStack::PushL(msConfigBuf);
   300 	
   257 	
   301 
   258 
   323 	ConfigItem(vendorId, iMsConfig.iVendorId, 8);
   280 	ConfigItem(vendorId, iMsConfig.iVendorId, 8);
   324 	ConfigItem(productId, iMsConfig.iProductId, 16);
   281 	ConfigItem(productId, iMsConfig.iProductId, 16);
   325 	ConfigItem(productRev, iMsConfig.iProductRev, 4);
   282 	ConfigItem(productRev, iMsConfig.iProductRev, 4);
   326 	
   283 	
   327 	// Debugging
   284 	// Debugging
   328 	OstTraceExt1( TRACE_NORMAL, CUSBMSCLASSCONTROLLER_READMASSSTORAGECONFIGL_DUP4, 
   285 	LOGTEXT2(_L8("vendorId = %S\n"), 	&vendorId);
   329 					"CUsbMsClassController::ReadMassStorageConfigL;vendorId = %S\n", vendorId );
   286 	LOGTEXT2(_L8("productId = %S\n"), 	&productId);
   330 
   287 	LOGTEXT2(_L8("productRev = %S\n"), 	&productRev);
   331 	OstTraceExt1( TRACE_NORMAL, CUSBMSCLASSCONTROLLER_READMASSSTORAGECONFIGL_DUP5, 
       
   332 					"CUsbMsClassController::ReadMassStorageConfigL;productId = %S\n", productId );
       
   333 
       
   334 	OstTraceExt1( TRACE_NORMAL, CUSBMSCLASSCONTROLLER_READMASSSTORAGECONFIGL_DUP6, 
       
   335 					"CUsbMsClassController::ReadMassStorageConfigL;productRev = %S\n", productRev );
       
   336 		
   288 		
   337 	CleanupStack::PopAndDestroy(3, &fs); // msConfigBuf, resource, fs		
   289 	CleanupStack::PopAndDestroy(3, &fs); // msConfigBuf, resource, fs		
   338 	OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_READMASSSTORAGECONFIGL_EXIT_DUP2 );
       
   339 	}
   290 	}
   340 	
   291 	
   341 /**
   292 /**
   342  Utility. Copies the data from TPtr to TBuf and checks data length 
   293  Utility. Copies the data from TPtr to TBuf and checks data length 
   343  to make sure the source does not exceed the capacity of the target
   294  to make sure the source does not exceed the capacity of the target
   344  */
   295  */
   345  void CUsbMsClassController::ConfigItem(const TPtrC& source, TDes& target, TInt maxLength)
   296  void CUsbMsClassController::ConfigItem(const TPtrC& source, TDes& target, TInt maxLength)
   346  	{
   297  	{
   347 	 OstTraceFunctionEntry0( CUSBMSCLASSCONTROLLER_CONFIGITEM_ENTRY );
       
   348  	if (source.Length() < maxLength)
   298  	if (source.Length() < maxLength)
   349  		{
   299  		{
   350  		maxLength = source.Length();
   300  		maxLength = source.Length();
   351  		}
   301  		}
   352  		
   302  		
   353  	target.Copy(source.Ptr(), maxLength);
   303  	target.Copy(source.Ptr(), maxLength);	 	
   354  	OstTraceFunctionExit0( CUSBMSCLASSCONTROLLER_CONFIGITEM_EXIT );
       
   355  	}
   304  	}
   356 
   305