author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Tue, 25 May 2010 14:09:55 +0300 | |
branch | RCL_3 |
changeset 28 | 5b5d147c7838 |
parent 21 | e7d2d738d3c2 |
permissions | -rw-r--r-- |
0 | 1 |
// Copyright (c) 1994-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 |
// e32\memmodel\emul\win32\mprocess.cpp |
|
15 |
// |
|
16 |
// |
|
17 |
||
18 |
#include "memmodel.h" |
|
19 |
#include <property.h> |
|
20 |
#include <emulator.h> |
|
21 |
#include <wchar.h> |
|
22 |
||
23 |
#define iMState iWaitLink.iSpare1 |
|
24 |
||
25 |
extern const char* JustInTime; |
|
26 |
extern TBool DisableWSDWarning; |
|
27 |
const TInt KMaxWsdDllsPerProcess = 256; |
|
28 |
||
29 |
/******************************************** |
|
30 |
* Process |
|
31 |
********************************************/ |
|
32 |
DWin32Process::DWin32Process() |
|
33 |
: iDllData(KMaxWsdDllsPerProcess, _FOFF(SProcessDllDataBlock,iCodeSeg)) |
|
34 |
{ |
|
35 |
// Set process JustInTime flag from the emulator property. This is not set |
|
36 |
// for the process containing supervisor thread. |
|
37 |
if (JustInTime && !_stricmp(JustInTime, "none")) |
|
38 |
{ |
|
39 |
iFlags &= !KProcessFlagJustInTime; |
|
40 |
} |
|
41 |
} |
|
42 |
||
43 |
DWin32Process::~DWin32Process() |
|
44 |
{ |
|
45 |
__KTRACE_OPT(KMMU,Kern::Printf("DWin32Process destruct")); |
|
46 |
Destruct(); |
|
47 |
RemoveDllData(); |
|
48 |
iDllData.Close(); |
|
49 |
} |
|
50 |
||
51 |
TInt DWin32Process::NewChunk(DChunk*& aChunk, SChunkCreateInfo& aInfo, TLinAddr& aRunAddr) |
|
52 |
{ |
|
53 |
aChunk=NULL; |
|
54 |
DWin32Chunk* pC=new DWin32Chunk; |
|
55 |
if (!pC) |
|
56 |
return KErrNoMemory; |
|
57 |
pC->iChunkType=aInfo.iType; |
|
58 |
if (!aInfo.iGlobal && (iAttributes & DWin32Process::EPrivate)!=0) |
|
59 |
pC->iAttributes |= DWin32Chunk::EPrivate; |
|
60 |
pC->iOwningProcess=(aInfo.iGlobal)?NULL:this; |
|
61 |
TInt r=pC->Create(aInfo); |
|
62 |
if (r==KErrNone && (aInfo.iOperations & SChunkCreateInfo::EAdjust)) |
|
63 |
{ |
|
64 |
__ASSERT_ALWAYS(aInfo.iRunAddress==0,MM::Panic(MM::EInvalidChunkCreate)); |
|
65 |
if (aInfo.iPreallocated==0) |
|
66 |
{ |
|
67 |
if (pC->iAttributes & DChunk::EDisconnected) |
|
68 |
{ |
|
69 |
r=pC->Commit(aInfo.iInitialBottom,aInfo.iInitialTop-aInfo.iInitialBottom); |
|
70 |
} |
|
71 |
else if (pC->iAttributes & DChunk::EDoubleEnded) |
|
72 |
{ |
|
73 |
r=pC->AdjustDoubleEnded(aInfo.iInitialBottom,aInfo.iInitialTop); |
|
74 |
} |
|
75 |
else |
|
76 |
{ |
|
77 |
r=pC->Adjust(aInfo.iInitialTop); |
|
78 |
} |
|
79 |
} |
|
80 |
if (r==KErrNone) |
|
81 |
{ |
|
82 |
aRunAddr=(TLinAddr)pC->Base(); |
|
83 |
} |
|
84 |
} |
|
85 |
if (r==KErrNone) |
|
86 |
{ |
|
87 |
pC->iDestroyedDfc = aInfo.iDestroyedDfc; |
|
88 |
aChunk=(DChunk*)pC; |
|
89 |
} |
|
90 |
else |
|
91 |
pC->Close(NULL); // NULL since chunk can't have been added to process |
|
92 |
return r; |
|
93 |
} |
|
94 |
||
95 |
TInt DWin32Process::DoCreate(TBool aKernelProcess, TProcessCreateInfo& /*aInfo*/) |
|
96 |
{ |
|
97 |
__KTRACE_OPT(KPROC,Kern::Printf("DWin32Process::DoCreate %O",this)) |
|
98 |
iAttributes=aKernelProcess ? ESupervisor|EPrivate : 0; |
|
99 |
// force iDllData to reserve KMaxWsdDllsPerProcess. The Append will |
|
100 |
// create the space, the Remove will not free it. |
|
101 |
SProcessDllDataBlock data = {0,0,0}; |
|
102 |
TInt err = iDllData.Append(data); |
|
103 |
if(err==KErrNone) |
|
104 |
{ |
|
105 |
__ASSERT_ALWAYS(iDllData.Count()==1,MM::Panic(MM::EWsdBadReserve)); |
|
106 |
iDllData.Remove(0); |
|
107 |
} |
|
108 |
return err; |
|
109 |
} |
|
110 |
||
111 |
TInt DWin32Process::CreateDataBssStackArea(TProcessCreateInfo& /*aInfo*/) |
|
112 |
// |
|
113 |
// This is managed for us by win32 |
|
114 |
// |
|
115 |
{ |
|
116 |
__KTRACE_OPT(KPROC,Kern::Printf("DWin32Process::CreateDataBssStackArea %O",this)); |
|
117 |
return KErrNone; |
|
118 |
} |
|
119 |
||
120 |
TInt DWin32Process::AddChunk(DChunk* /*aChunk*/,TBool /*isReadOnly*/) |
|
121 |
{ |
|
122 |
return KErrNone; |
|
123 |
} |
|
124 |
||
125 |
||
126 |
TInt DWin32Process::NewShPool(DShPool*& aPool, TShPoolCreateInfo& aInfo) |
|
127 |
{ |
|
128 |
aPool = NULL; |
|
129 |
DWin32ShPool* pC = NULL; |
|
130 |
||
131 |
if (aInfo.iInfo.iFlags & TShPoolCreateInfo::EPageAlignedBuffer) |
|
132 |
{ |
|
133 |
pC = new DWin32AlignedShPool(); |
|
134 |
} |
|
135 |
else |
|
136 |
{ |
|
137 |
pC = new DWin32NonAlignedShPool(); |
|
138 |
} |
|
139 |
||
140 |
if (pC == NULL) |
|
141 |
{ |
|
142 |
return KErrNoMemory; |
|
143 |
} |
|
144 |
||
145 |
TInt r = pC->Create(this, aInfo); |
|
146 |
||
147 |
if (r == KErrNone) |
|
148 |
{ |
|
149 |
aPool = pC; |
|
150 |
} |
|
151 |
else |
|
152 |
{ |
|
153 |
pC->Close(NULL); |
|
154 |
} |
|
155 |
||
156 |
return r; |
|
157 |
} // DWin32Process::NewShPool |
|
158 |
||
159 |
||
160 |
void DWin32Process::Release() |
|
161 |
{ |
|
162 |
CallRuntimeHook(EWin32RuntimeProcessDetach); |
|
163 |
DProcess::Release(); |
|
164 |
} |
|
165 |
||
166 |
void DWin32Process::FinalRelease() |
|
167 |
{ |
|
168 |
} |
|
169 |
||
170 |
TInt DWin32Process::MapCodeSeg(DCodeSeg* aSeg) |
|
171 |
{ |
|
172 |
||
173 |
__KTRACE_OPT(KDLL,Kern::Printf("Process %O MapCodeSeg(%C)", this, aSeg)); |
|
174 |
if (!aSeg || !aSeg->IsDll()) |
|
175 |
return KErrNone; |
|
176 |
||
177 |
DWin32CodeSeg* seg = (DWin32CodeSeg*)aSeg; |
|
178 |
if (seg->iRealDataSize == 0 && seg->iRealBssSize == 0) |
|
179 |
return KErrNone; |
|
180 |
||
181 |
if (!DisableWSDWarning && this!=K::TheKernelProcess) |
|
182 |
Kern::Printf("WARNING!!: WSD Lib Loaded- Process %O, has loaded Lib %C" |
|
183 |
" which has %d bytes of WSD",this,aSeg, |
|
184 |
seg->iRealDataSize + seg->iRealBssSize); |
|
185 |
||
186 |
// remove any existing copy of this code seg (should never happen) |
|
187 |
UnmapCodeSeg(aSeg); |
|
188 |
||
189 |
SProcessDllDataBlock data; |
|
190 |
data.iCodeSeg = seg; |
|
191 |
||
192 |
TInt count=0; |
|
193 |
TInt err = KErrNone; |
|
21
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
194 |
|
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
195 |
// Scheduling must be disabled while we are allocating memory from Windows' heap |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
196 |
NKern::Lock(); |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
197 |
data.iDataCopy = GlobalAlloc(GMEM_FIXED, seg->iRealDataSize); |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
198 |
data.iBssCopy = GlobalAlloc(GMEM_FIXED, seg->iRealBssSize); |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
199 |
NKern::Unlock(); |
0 | 200 |
if (!data.iDataCopy || !data.iBssCopy) |
201 |
{ |
|
202 |
err = KErrNoMemory; |
|
203 |
goto failed; |
|
204 |
} |
|
21
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
205 |
|
0 | 206 |
memcpy(data.iDataCopy, seg->iDataCopy, seg->iRealDataSize); // start with init data |
207 |
memclr(data.iBssCopy, seg->iRealBssSize); // initialized to zeros |
|
208 |
||
209 |
NKern::Lock(); |
|
210 |
count = iDllData.Count(); |
|
211 |
if (count == KMaxWsdDllsPerProcess) |
|
212 |
err = KErrOverflow; |
|
213 |
if (!err) |
|
214 |
err = iDllData.InsertInUnsignedKeyOrder(data); |
|
215 |
NKern::Unlock(); |
|
216 |
if (err) |
|
217 |
goto failed; |
|
218 |
||
219 |
return KErrNone; |
|
220 |
||
221 |
failed: |
|
21
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
222 |
// Scheduling must be disabled while we are freeing memory from Windows' heap |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
223 |
NKern::Lock(); |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
224 |
GlobalFree(data.iDataCopy); |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
225 |
GlobalFree(data.iBssCopy); |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
226 |
NKern::Unlock(); |
0 | 227 |
|
228 |
return err; |
|
229 |
} |
|
230 |
||
231 |
void DWin32Process::UnmapCodeSeg(DCodeSeg* aSeg) |
|
232 |
{ |
|
233 |
if (!aSeg || !aSeg->IsDll()) |
|
234 |
return; |
|
235 |
||
236 |
DWin32CodeSeg* seg = (DWin32CodeSeg*)aSeg; |
|
237 |
if (seg->iRealDataSize == 0 && seg->iRealBssSize == 0) |
|
238 |
return; |
|
239 |
||
240 |
SProcessDllDataBlock data; |
|
241 |
data.iCodeSeg = seg; |
|
242 |
NKern::Lock(); |
|
243 |
if (seg->iLiveProcess == this) |
|
244 |
seg->iLiveProcess = NULL; |
|
245 |
TInt ix = iDllData.FindInUnsignedKeyOrder(data); |
|
246 |
if (ix >= 0) |
|
247 |
{ |
|
248 |
data = iDllData[ix]; |
|
249 |
iDllData.Remove(ix); |
|
250 |
} |
|
251 |
NKern::Unlock(); |
|
252 |
||
253 |
if (ix < 0) |
|
254 |
return; |
|
21
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
255 |
|
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
256 |
// Scheduling must be disabled while we are freeing memory from Windows' heap |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
257 |
NKern::Lock(); |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
258 |
GlobalFree(data.iDataCopy); |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
259 |
GlobalFree(data.iBssCopy); |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
260 |
NKern::Unlock(); |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
261 |
|
0 | 262 |
__KTRACE_OPT(KDLL,Kern::Printf("Process %O UnmapCodeSeg(%C)", this, aSeg)); |
263 |
} |
|
264 |
||
265 |
void DWin32Process::RemoveDllData() |
|
266 |
{ |
|
267 |
// unmap all DLL data with kernel locked |
|
268 |
TInt count = iDllData.Count(); |
|
269 |
for (TInt ii=count-1; ii>=0; ii--) |
|
270 |
{ |
|
271 |
SProcessDllDataBlock data = iDllData[ii]; |
|
272 |
NKern::Lock(); |
|
273 |
if (data.iCodeSeg->iLiveProcess == this) |
|
274 |
data.iCodeSeg->iLiveProcess = NULL; |
|
21
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
275 |
iDllData.Remove(ii); |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
276 |
GlobalFree(data.iDataCopy); |
e7d2d738d3c2
Revision: 201010
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
277 |
GlobalFree(data.iBssCopy); |
0 | 278 |
NKern::Unlock(); |
279 |
} |
|
280 |
} |
|
281 |
||
282 |
TInt DWin32Process::AttachExistingCodeSeg(TProcessCreateInfo& /*aInfo*/) |
|
283 |
{ |
|
284 |
return KErrNotSupported; // never allowed |
|
285 |
} |
|
286 |
||
287 |
void DWin32Process::CallRuntimeHook(TWin32RuntimeReason aReason) |
|
288 |
{ |
|
289 |
if (iWin32RuntimeHook) |
|
290 |
{ |
|
291 |
SchedulerLock(); |
|
292 |
TBool ok = iWin32RuntimeHook(aReason); |
|
293 |
SchedulerUnlock(); |
|
294 |
if (!ok && aReason != EWin32RuntimeProcessDetach) |
|
295 |
Kern::PanicCurrentThread(_L("MemModel"), MM::EWin32RuntimeError); |
|
296 |
} |
|
297 |
} |
|
298 |
||
299 |
||
300 |
void DThread::IpcExcHandler(TExcTrap* aTrap, DThread* aThread, TAny* aContext) |
|
301 |
{ |
|
302 |
aThread->iIpcClient = 0; |
|
303 |
TIpcExcTrap& xt=*(TIpcExcTrap*)aTrap; |
|
304 |
TWin32ExcInfo& info=*(TWin32ExcInfo*)aContext; |
|
305 |
TLinAddr va=(TLinAddr)info.iExcDataAddress; |
|
306 |
if (va>=xt.iRemoteBase && (va-xt.iRemoteBase)<xt.iSize) |
|
307 |
xt.Exception(KErrBadDescriptor); // problem accessing remote address - 'leave' so an error code will be returned |
|
308 |
if (xt.iLocalBase && va>=xt.iLocalBase && (va-xt.iLocalBase)<xt.iSize) |
|
309 |
NKern::UnlockSystem(); // problem accessing local address - return and panic current thread as usual |
|
310 |
// otherwise return and fault kernel |
|
311 |
} |
|
312 |
||
313 |
TInt DThread::RawRead(const TAny* aSrc, TAny* aDest, TInt aLength, TInt /*aFlags*/, TIpcExcTrap* /*aExcTrap*/) |
|
314 |
// |
|
315 |
// Read from the thread's process. |
|
316 |
// aSrc is run address of memory to read |
|
317 |
// aDest is current address of destination |
|
318 |
// Enter and leave with system locked |
|
319 |
// |
|
320 |
{ |
|
321 |
if (iMState==EDead) |
|
322 |
return KErrDied; |
|
323 |
const TUint8* pS=(const TUint8*)aSrc; |
|
324 |
TUint8* pD=(TUint8*)aDest; |
|
325 |
TBool kernelLocked = EFalse; |
|
326 |
const TUint8* pC=(const TUint8*)MM::CurrentAddress(this,pS,aLength,EFalse,kernelLocked); |
|
327 |
if (kernelLocked) |
|
328 |
{ |
|
329 |
// kernel locked because of DLL WSD IPC, do it all in one big block |
|
330 |
TInt r = KErrNone; |
|
331 |
__KTRACE_OPT(KTHREAD2,Kern::Printf("DThread::RawRead %08x",pC)); |
|
332 |
if (!pC) |
|
333 |
r = KErrBadDescriptor; |
|
334 |
else |
|
335 |
memcpy(pD,pC,aLength); |
|
336 |
NKern::Unlock(); |
|
337 |
return r; |
|
338 |
} |
|
339 |
TBool check=ETrue; |
|
340 |
while (aLength) |
|
341 |
{ |
|
342 |
if (check) |
|
343 |
{ |
|
344 |
if (iMState==EDead) |
|
345 |
return KErrDied; |
|
346 |
__KTRACE_OPT(KTHREAD2,Kern::Printf("DThread::Read %08x",pS)); |
|
347 |
} |
|
348 |
TInt l=Min(aLength,K::MaxMemCopyInOneGo); |
|
349 |
memcpy(pD,pS,l); |
|
350 |
pD+=l; |
|
351 |
pS+=l; |
|
352 |
aLength-=l; |
|
353 |
if (aLength) |
|
354 |
check=NKern::FlashSystem(); |
|
355 |
} |
|
356 |
return KErrNone; |
|
357 |
} |
|
358 |
||
359 |
TInt DThread::RawWrite(const TAny* aDest, const TAny* aSrc, TInt aLength, TInt /*aFlags*/, DThread* /*anOriginatingThread*/, TIpcExcTrap* /*aExcTrap*/) |
|
360 |
// |
|
361 |
// Write to the thread's process. |
|
362 |
// aDest is run address of memory to write |
|
363 |
// aSrc is current address of destination |
|
364 |
// anOriginatingThread is the thread on behalf of which this operation is performed (eg client of device driver). |
|
365 |
// Enter and leave with system locked |
|
366 |
// |
|
367 |
{ |
|
368 |
if (iMState==EDead) |
|
369 |
return KErrDied; |
|
370 |
TUint8* pD=(TUint8*)aDest; |
|
371 |
const TUint8* pS=(const TUint8*)aSrc; |
|
372 |
TBool kernelLocked = EFalse; |
|
373 |
TUint8* pC=(TUint8*)MM::CurrentAddress(this,pD,aLength,ETrue,kernelLocked); |
|
374 |
if (kernelLocked) |
|
375 |
{ |
|
376 |
// kernel locked because of DLL WSD IPC, do it all in one big block |
|
377 |
TInt r = KErrNone; |
|
378 |
__KTRACE_OPT(KTHREAD2,Kern::Printf("DThread::RawWrite %08x",pC)); |
|
379 |
if (!pC) |
|
380 |
r = KErrBadDescriptor; |
|
381 |
else |
|
382 |
memcpy(pC,pS,aLength); |
|
383 |
NKern::Unlock(); |
|
384 |
return r; |
|
385 |
} |
|
386 |
TBool check=ETrue; |
|
387 |
while (aLength) |
|
388 |
{ |
|
389 |
if (check) |
|
390 |
{ |
|
391 |
if (iMState==EDead) |
|
392 |
return KErrDied; |
|
393 |
__KTRACE_OPT(KTHREAD2,Kern::Printf("DThread::Write %08x",pD)); |
|
394 |
} |
|
395 |
TInt l=Min(aLength,K::MaxMemCopyInOneGo); |
|
396 |
memcpy(pD,pS,l); |
|
397 |
pD+=l; |
|
398 |
pS+=l; |
|
399 |
aLength-=l; |
|
400 |
if (aLength) |
|
401 |
check=NKern::FlashSystem(); |
|
402 |
} |
|
403 |
return KErrNone; |
|
404 |
} |
|
405 |
||
406 |
TInt DThread::ReadAndParseDesHeader(const TAny* aSrc, TDesHeader& aDest) |
|
407 |
// |
|
408 |
// Read and parse the header of a remote descriptor. |
|
409 |
// Enter and leave with system locked. |
|
410 |
// |
|
411 |
{ |
|
412 |
__ASSERT_SYSTEM_LOCK; |
|
413 |
static const TUint8 LengthLookup[16]={4,8,12,8,12,0,0,0,0,0,0,0,0,0,0,0}; |
|
414 |
if (iMState == EDead) |
|
415 |
return KErrDied; |
|
416 |
TBool kernelLocked = EFalse; |
|
417 |
const TUint32* pS=(const TUint32*)MM::CurrentAddress(this,aSrc,sizeof(TDesC8),EFalse,kernelLocked); |
|
418 |
if (!pS || (TInt(pS)&3)!=0) |
|
419 |
{ |
|
420 |
if (kernelLocked) |
|
421 |
NKern::Unlock(); |
|
422 |
return KErrBadDescriptor; |
|
423 |
} |
|
424 |
TInt type=0; |
|
425 |
XTRAPD(r, XT_DEFAULT, \ |
|
426 |
type=*pS>>KShiftDesType8; \ |
|
427 |
TInt l=LengthLookup[type]; \ |
|
428 |
if (l==0) \ |
|
429 |
r=KErrBadDescriptor; \ |
|
430 |
else \ |
|
431 |
wordmove(&aDest,pS,l); \ |
|
432 |
); |
|
433 |
if (kernelLocked) |
|
434 |
NKern::Unlock(); |
|
435 |
if (r!=KErrNone) |
|
436 |
return r; |
|
437 |
return K::ParseDesHeader(aSrc, (TRawDesHeader&)aDest, aDest); |
|
438 |
} |
|
439 |
||
440 |
DChunk* DThread::OpenSharedChunk(const TAny* aAddress, TBool /*aWrite*/, TInt& aOffset) |
|
441 |
{ |
|
442 |
DWin32Chunk* chunk=0; |
|
443 |
DObjectCon& chunks=*K::Containers[EChunk]; |
|
444 |
chunks.Wait(); |
|
445 |
TInt count=chunks.Count(); |
|
446 |
TInt i; |
|
447 |
TUint offset=0; |
|
448 |
for(i=0;i<count;i++) |
|
449 |
{ |
|
450 |
DWin32Chunk* pC=(DWin32Chunk*)chunks[i]; |
|
451 |
offset = (TUint)aAddress-(TUint)pC->Base(); |
|
452 |
if(offset<TUint(pC->iMaxSize)) |
|
453 |
{ |
|
454 |
chunk = pC; |
|
455 |
break; |
|
456 |
} |
|
457 |
} |
|
458 |
chunks.Signal(); |
|
459 |
||
460 |
if(!chunk) |
|
461 |
return 0; |
|
462 |
||
463 |
if((chunk->iChunkType!=ESharedKernelSingle && chunk->iChunkType!=ESharedKernelMultiple)) |
|
464 |
return 0; |
|
465 |
if(chunk->Open()!=KErrNone) |
|
466 |
return 0; |
|
467 |
aOffset = offset; |
|
468 |
return chunk; |
|
469 |
} |
|
470 |
||
471 |
TInt DThread::PrepareMemoryForDMA(const TAny* /*aLinAddr*/, TInt /*aSize*/, TPhysAddr* /*aPhysicalPageList*/) |
|
472 |
{ |
|
473 |
return KErrNotSupported; |
|
474 |
} |
|
475 |
||
476 |
TInt DThread::ReleaseMemoryFromDMA(const TAny* /*aLinAddr*/, TInt /*aSize*/, TPhysAddr* /*aPhysicalPageList*/) |
|
477 |
{ |
|
478 |
return KErrNotSupported; |
|
479 |
} |
|
480 |