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