os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_dir.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// f32\sfile\sf_dir.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include "sf_std.h"
sl@0
    19
sl@0
    20
LOCAL_C CDirCB* GetDirFromHandle(TInt aHandle,CSessionFs* aSession)
sl@0
    21
//
sl@0
    22
// Get the dir control block from its handle.
sl@0
    23
//
sl@0
    24
	{
sl@0
    25
	return((CDirCB*)(SessionObjectFromHandle(aHandle,Dirs->UniqueID(),aSession)));
sl@0
    26
	}
sl@0
    27
sl@0
    28
LOCAL_C TInt DoInitialise(CFsRequest* aRequest)
sl@0
    29
//
sl@0
    30
//	Determine asynchronicity from dir control block
sl@0
    31
//
sl@0
    32
	{
sl@0
    33
	CDirCB* dir;
sl@0
    34
	dir=GetDirFromHandle(aRequest->Message().Int3(),aRequest->Session());
sl@0
    35
	if(!dir)
sl@0
    36
		return(KErrBadHandle);
sl@0
    37
	aRequest->SetDrive(&dir->Drive());
sl@0
    38
	aRequest->SetScratchValue((TUint)dir);
sl@0
    39
	return KErrNone;
sl@0
    40
	}
sl@0
    41
sl@0
    42
#ifndef __ARMCC__
sl@0
    43
LOCAL_C 
sl@0
    44
#endif
sl@0
    45
void fsDirReadPacked(TEntry* pE,TEntry* pEnd,volatile TInt& aLen,CDirCB& aDir)
sl@0
    46
//
sl@0
    47
// Read packed directory entries.
sl@0
    48
//
sl@0
    49
	{
sl@0
    50
sl@0
    51
	FOREVER
sl@0
    52
		{
sl@0
    53
		TEntry e;
sl@0
    54
sl@0
    55
		TRACE1(UTF::EBorder, UTraceModuleFileSys::ECDirCBReadL, EF32TraceUidFileSys, &aDir);
sl@0
    56
		aDir.ReadL(e);
sl@0
    57
		TRACE5(UTF::EBorder, UTraceModuleFileSys::ECDirCBReadLRet, EF32TraceUidFileSys, 
sl@0
    58
			KErrNone, e.iAtt, I64LOW(e.iModified.Int64()), I64HIGH(e.iModified.Int64()), e.iSize);
sl@0
    59
		TInt len=EntrySize(e, EFalse);
sl@0
    60
		TInt rLen=EntrySize(e, ETrue);
sl@0
    61
		TEntry* pX=PtrAdd(pE,rLen);
sl@0
    62
		if (pX>pEnd)
sl@0
    63
			{
sl@0
    64
sl@0
    65
			TRACE1(UTF::EBorder, UTraceModuleFileSys::ECDirCBStoreLongEntryNameL, EF32TraceUidFileSys, &aDir);
sl@0
    66
			aDir.StoreLongEntryNameL(e.iName);
sl@0
    67
			TRACE1(UTF::EBorder, UTraceModuleFileSys::ECDirCBStoreLongEntryNameLRet, EF32TraceUidFileSys, KErrNone);
sl@0
    68
sl@0
    69
			aDir.SetPending(ETrue);
sl@0
    70
			break;
sl@0
    71
			}
sl@0
    72
		aLen+=rLen;
sl@0
    73
		Mem::Copy(pE,&e,len);
sl@0
    74
sl@0
    75
		/**
sl@0
    76
		 * Flag the entry with KEntryAttPacked so we can unpack
sl@0
    77
		 * these fields as required at a later date...
sl@0
    78
		 */
sl@0
    79
		pE->iAtt |= KEntryAttPacked;
sl@0
    80
sl@0
    81
		/**
sl@0
    82
		 * ...and pack the iSizeHigh and iReserved fields to the end of the name string
sl@0
    83
		 */
sl@0
    84
		TUint32* pSizeHighSrc = PtrAdd((TUint32*)&e, sizeof(TEntry) - 2*sizeof(TInt));
sl@0
    85
		TUint32* pSizeHighDst = PtrAdd((TUint32*)pE, EntrySize(*pE, EFalse));
sl@0
    86
sl@0
    87
		*pSizeHighDst++ = *pSizeHighSrc++;	// Copy length
sl@0
    88
		*pSizeHighDst   = *pSizeHighSrc;	// Copy reserved
sl@0
    89
sl@0
    90
		pE=pX;
sl@0
    91
		}
sl@0
    92
	}
sl@0
    93
sl@0
    94
TInt TFsDirOpen::DoRequestL(CFsRequest* aRequest)
sl@0
    95
//
sl@0
    96
// Open a directory.
sl@0
    97
//
sl@0
    98
	{
sl@0
    99
sl@0
   100
	__PRINT(_L("TFsDirOpen::DoRequestL(CFsRequest* aRequest)"));
sl@0
   101
	TInt h;
sl@0
   102
	TUidType uidType;
sl@0
   103
	TPckgBuf<TUidType> pckgUid;
sl@0
   104
	aRequest->ReadL(KMsgPtr2,pckgUid);
sl@0
   105
	uidType=pckgUid();
sl@0
   106
	TInt r=aRequest->Drive()->DirOpen(aRequest->Session(),h,aRequest->Src().FullName().Mid(2),aRequest->Message().Int1(),uidType);
sl@0
   107
	if (r!=KErrNone)
sl@0
   108
		return(r);
sl@0
   109
sl@0
   110
	
sl@0
   111
	//DirRead does not have a filename / src stored, so if there are plugins installed which
sl@0
   112
	//wish to intercept dirread1/packed then store the name in CDirCB::iName now.
sl@0
   113
	CFsPlugin* plugin = NULL;
sl@0
   114
	//Get the next plugin which is mounted on this drive (IsMounted called in NextPlugin)
sl@0
   115
	//Do not check whether we're registered for current operation (in case not registered for EFsDirOpen)
sl@0
   116
	while(FsPluginManager::NextPlugin(plugin,(CFsMessageRequest*)aRequest,(TBool)ETrue,(TBool)EFalse)==KErrNone && plugin)
sl@0
   117
		{
sl@0
   118
		if(plugin->IsRegistered(EFsDirReadOne) ||
sl@0
   119
			plugin->IsRegistered(EFsDirReadPacked) ||
sl@0
   120
			plugin->IsRegistered(EFsDirSubClose))
sl@0
   121
			{
sl@0
   122
			CDirCB* dir = GetDirFromHandle(h,aRequest->Session());
sl@0
   123
			TPtrC name = aRequest->Src().FullName();
sl@0
   124
			r = dir->SetName(&name);
sl@0
   125
			CheckForLeaveAfterOpenL(r, aRequest, h);
sl@0
   126
			break;
sl@0
   127
			}
sl@0
   128
		}
sl@0
   129
	
sl@0
   130
	TPtrC8 pH((TUint8*)&h,sizeof(TInt));
sl@0
   131
	TRAP(r,aRequest->WriteL(KMsgPtr3,pH))
sl@0
   132
	CheckForLeaveAfterOpenL(r, aRequest, h);
sl@0
   133
	aRequest->Session()->IncResourceCount();
sl@0
   134
	return(KErrNone);
sl@0
   135
	}
sl@0
   136
sl@0
   137
sl@0
   138
TInt TFsDirOpen::Initialise(CFsRequest* aRequest)
sl@0
   139
//
sl@0
   140
//
sl@0
   141
//	
sl@0
   142
	{
sl@0
   143
	
sl@0
   144
	TInt r=ParseSubstPtr0(aRequest,aRequest->Src());
sl@0
   145
	if (r!=KErrNone)
sl@0
   146
		return(r);
sl@0
   147
	r=PathCheck(aRequest,aRequest->Src().FullName().Mid(2),&KCapFsSysDirOpen,&KCapFsPriDirOpen, __PLATSEC_DIAGNOSTIC_STRING("Dir Open"));
sl@0
   148
	if(r != KErrNone)
sl@0
   149
		return r;
sl@0
   150
	return KErrNone;
sl@0
   151
	}
sl@0
   152
sl@0
   153
sl@0
   154
TInt TFsDirReadOne::DoRequestL(CFsRequest* aRequest)
sl@0
   155
//
sl@0
   156
// Read one directory entry.
sl@0
   157
//
sl@0
   158
	{
sl@0
   159
	__PRINT(_L("TFsDirReadOne::DoRequestL(CFsRequest* aRequest)"));
sl@0
   160
	CDirCB* dir=(CDirCB*)aRequest->ScratchValue();
sl@0
   161
	TInt r=dir->CheckMount();
sl@0
   162
	if (r!=KErrNone)
sl@0
   163
		return(r);
sl@0
   164
	TEntry e;
sl@0
   165
sl@0
   166
	TRACE1(UTF::EBorder, UTraceModuleFileSys::ECDirCBReadL, EF32TraceUidFileSys, &dir);
sl@0
   167
	TRAP(r,dir->ReadL(e))
sl@0
   168
	TRACE5(UTF::EBorder, UTraceModuleFileSys::ECDirCBReadLRet, EF32TraceUidFileSys, 
sl@0
   169
		KErrNone, e.iAtt, I64LOW(e.iModified.Int64()), I64HIGH(e.iModified.Int64()), e.iSize);
sl@0
   170
sl@0
   171
sl@0
   172
	if (r==KErrNone)
sl@0
   173
		{
sl@0
   174
		TPckgC<TEntry> pE(e);
sl@0
   175
		aRequest->WriteL(KMsgPtr0,pE);
sl@0
   176
		}
sl@0
   177
	return(r);
sl@0
   178
	}
sl@0
   179
sl@0
   180
TInt TFsDirReadOne::Initialise(CFsRequest* aRequest)
sl@0
   181
//
sl@0
   182
//
sl@0
   183
//	
sl@0
   184
	{
sl@0
   185
	return(DoInitialise(aRequest));
sl@0
   186
	}
sl@0
   187
sl@0
   188
TInt TFsDirReadPacked::DoRequestL(CFsRequest* aRequest)
sl@0
   189
//
sl@0
   190
// Read packed directory entries.
sl@0
   191
//
sl@0
   192
	{
sl@0
   193
sl@0
   194
	__PRINT(_L("TFsDirReadPacked::DoRequestL(CFsRequest* aRequest)"));
sl@0
   195
	CDirCB* dir=(CDirCB*)aRequest->ScratchValue();
sl@0
   196
	TInt r=dir->CheckMount();
sl@0
   197
	if (r!=KErrNone)
sl@0
   198
		return(r);
sl@0
   199
sl@0
   200
	TBuf8<KEntryArraySize> buf;
sl@0
   201
	TEntry* pE=(TEntry*)buf.Ptr();
sl@0
   202
	TEntry* pEnd=PtrAdd(pE,KEntryArraySize);
sl@0
   203
	volatile TInt len=0;
sl@0
   204
	TRAP(r,fsDirReadPacked(pE,pEnd,len,*(dir)));
sl@0
   205
	buf.SetLength(len);
sl@0
   206
	aRequest->WriteL(KMsgPtr0,buf);
sl@0
   207
	return(r);
sl@0
   208
	}
sl@0
   209
sl@0
   210
TInt TFsDirReadPacked::Initialise(CFsRequest* aRequest)
sl@0
   211
//
sl@0
   212
//	Call GetDirFromHandle to determine asynchronicity ***
sl@0
   213
//	
sl@0
   214
	{
sl@0
   215
	return(DoInitialise(aRequest));
sl@0
   216
	}
sl@0
   217
sl@0
   218
sl@0
   219
sl@0
   220
sl@0
   221
/**
sl@0
   222
Default cosntructor.
sl@0
   223
*/
sl@0
   224
EXPORT_C CDirCB::CDirCB()
sl@0
   225
	{
sl@0
   226
sl@0
   227
//	iPending=EFalse;
sl@0
   228
//	iDrive=NULL;
sl@0
   229
//	iMount=NULL;
sl@0
   230
	}
sl@0
   231
sl@0
   232
sl@0
   233
sl@0
   234
sl@0
   235
/**
sl@0
   236
Destructor.
sl@0
   237
sl@0
   238
Frees resources before destruction of the object.
sl@0
   239
*/
sl@0
   240
EXPORT_C CDirCB::~CDirCB()
sl@0
   241
	{
sl@0
   242
	if(iMount)
sl@0
   243
		{
sl@0
   244
		RemoveResource(*iMount);
sl@0
   245
		iMount->Close();
sl@0
   246
		}
sl@0
   247
	}
sl@0
   248
sl@0
   249
TInt CDirCB::CheckMount()
sl@0
   250
//
sl@0
   251
// Check that the media is still mounted.
sl@0
   252
//
sl@0
   253
	{
sl@0
   254
sl@0
   255
	TDrive& d=Drive();
sl@0
   256
	TInt r=d.CheckMount();
sl@0
   257
	if (r!=KErrNone)
sl@0
   258
		return(r);
sl@0
   259
	if (&Mount()!=&d.CurrentMount())
sl@0
   260
		return(KErrDisMounted);
sl@0
   261
	return(KErrNone);
sl@0
   262
	}
sl@0
   263
sl@0
   264
EXPORT_C void CDirCB::InitL(TDrive* aDrive)
sl@0
   265
//
sl@0
   266
// Initialise
sl@0
   267
//
sl@0
   268
	{
sl@0
   269
	DoInitL(aDrive->DriveNumber());
sl@0
   270
	iDrive=aDrive;
sl@0
   271
	iMount=&aDrive->CurrentMount();
sl@0
   272
	User::LeaveIfError(iMount->Open());
sl@0
   273
	}
sl@0
   274
sl@0
   275
sl@0
   276
sl@0
   277
sl@0
   278
/**
sl@0
   279
Stores a long full entry name, a TEntry::iName value, into a buffer,
sl@0
   280
re-allocating the buffer first, if necessary, to make it large enough.
sl@0
   281
sl@0
   282
The function should be implemented by a derived class; this implementation
sl@0
   283
is empty.
sl@0
   284
sl@0
   285
This function is called by a file server reading successive entries,
sl@0
   286
when the file server reads an entry for which the full file name is longer than
sl@0
   287
the maximum buffer size. Once this function has been called, the iPending flag
sl@0
   288
is set to true by the file server and, on the next call to ReadL(),
sl@0
   289
the buffer created in this function is used to store the long entry name.
sl@0
   290
sl@0
   291
The function should leave with an appropriate error code on error detection.
sl@0
   292
sl@0
   293
@param aName The name to be set to a newly read entry.
sl@0
   294
*/
sl@0
   295
EXPORT_C void CDirCB::StoreLongEntryNameL(const TDesC& /*aName*/)
sl@0
   296
	{}
sl@0
   297
sl@0
   298
	
sl@0
   299
EXPORT_C TInt CDirCB::GetInterface(TInt /*aInterfaceId*/,TAny*& /*aInterface*/,TAny* /*aInput*/)
sl@0
   300
	{
sl@0
   301
	return(KErrNotSupported);
sl@0
   302
	}
sl@0
   303