0
|
1 |
// Copyright (c) 1998-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\klib\kdes8.cpp
|
|
15 |
//
|
|
16 |
//
|
|
17 |
|
|
18 |
#include <kernel/kernel.h>
|
|
19 |
#include <kernel/kern_priv.h>
|
|
20 |
|
|
21 |
/**
|
|
22 |
Creates, and returns a pointer to, a new 8-bit heap descriptor.
|
|
23 |
|
|
24 |
On construction, the heap descriptor is empty and has zero length.
|
|
25 |
|
|
26 |
@param aMaxLength The requested maximum length of the descriptor.
|
|
27 |
This value must be non-negative otherwise the current thread
|
|
28 |
is panicked.
|
|
29 |
Note that the resulting heap cell size and, therefore, the
|
|
30 |
resulting maximum length of the descriptor may be larger than
|
|
31 |
requested.
|
|
32 |
@return A pointer to the new 8-bit heap descriptor; NULL,
|
|
33 |
if the descriptor cannot be created.
|
|
34 |
|
|
35 |
@pre Calling thread must be in a critical section.
|
|
36 |
@pre Interrupts must be enabled.
|
|
37 |
@pre Kernel must be unlocked.
|
|
38 |
@pre No fast mutex can be held.
|
|
39 |
@pre Call in a thread context.
|
|
40 |
@pre Can be used in a device driver.
|
|
41 |
|
|
42 |
@post Calling thread is in a critical section.
|
|
43 |
|
|
44 |
@panic KernLib 30, if the requested maximum length is negative.
|
|
45 |
*/
|
|
46 |
EXPORT_C HBuf8* HBuf8::New(TInt aMaxLength)
|
|
47 |
{
|
|
48 |
CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"HBuf8::New(TInt aMaxLength)");
|
|
49 |
__ASSERT_ALWAYS(aMaxLength>=0,KL::Panic(KL::ETDes8MaxLengthNegative));
|
|
50 |
TAny* pM=Kern::Alloc(aMaxLength*sizeof(TUint8)+sizeof(TBufBase8));
|
|
51 |
if (pM)
|
|
52 |
new (pM) HBuf8(aMaxLength);
|
|
53 |
return (HBuf8*)pM;
|
|
54 |
}
|
|
55 |
|
|
56 |
|
|
57 |
/**
|
|
58 |
Creates, and returns a pointer to, a new 8-bit heap descriptor, and copies the
|
|
59 |
content of the specified descriptor into it.
|
|
60 |
|
|
61 |
Both the length and the maximum length of the new heap descriptor are set to
|
|
62 |
the same value as the length of the specified descriptor.
|
|
63 |
|
|
64 |
@param aDes The descriptor whose content is to be copied into the new heap
|
|
65 |
descriptor.
|
|
66 |
|
|
67 |
@pre Calling thread must be in a critical section.
|
|
68 |
@pre Interrupts must be enabled.
|
|
69 |
@pre Kernel must be unlocked.
|
|
70 |
@pre No fast mutex can be held.
|
|
71 |
@pre Call in a thread context.
|
|
72 |
@pre Can be used in a device driver.
|
|
73 |
|
|
74 |
@post Calling thread is in a critical section.
|
|
75 |
|
|
76 |
@return A pointer to the new 8-bit heap descriptor; NULL,
|
|
77 |
if the descriptor cannot be created.
|
|
78 |
*/
|
|
79 |
EXPORT_C HBuf8* HBuf8::New(const TDesC8& aDes)
|
|
80 |
{
|
|
81 |
CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"HBuf8::New(const TDesC8& aDes)");
|
|
82 |
HBuf8* pB=HBuf8::New(aDes.Length());
|
|
83 |
if (pB)
|
|
84 |
pB->Copy(aDes);
|
|
85 |
return pB;
|
|
86 |
}
|
|
87 |
|
|
88 |
|
|
89 |
/**
|
|
90 |
Expands or contracts the heap descriptor.
|
|
91 |
|
|
92 |
This is done by: creating a new heap descriptor, copying the original data
|
|
93 |
into the new descriptor, and then deleting the original descriptor.
|
|
94 |
|
|
95 |
@param aNewMax The requested maximum length of data that the new descriptor
|
|
96 |
is to represent.This value must be non-negative and it must not
|
|
97 |
be less than the length of any existing data, otherwise the
|
|
98 |
current thread is panicked.
|
|
99 |
Note that the resulting heap cell size and, therefore, the
|
|
100 |
resulting maximum length of the descriptor may be larger than
|
|
101 |
requested.
|
|
102 |
|
|
103 |
@return A pointer to the new expanded or contracted 8-bit heap descriptor;
|
|
104 |
the original descriptor is deleted. NULL, if the new 8-bit heap
|
|
105 |
descriptor cannot be created - the original descriptor remains unchanged.
|
|
106 |
|
|
107 |
@pre Calling thread must be in a critical section.
|
|
108 |
@pre Interrupts must be enabled.
|
|
109 |
@pre Kernel must be unlocked.
|
|
110 |
@pre No fast mutex can be held.
|
|
111 |
@pre Call in a thread context.
|
|
112 |
@pre Can be used in a device driver.
|
|
113 |
|
|
114 |
@post Calling thread is in a critical section.
|
|
115 |
|
|
116 |
@panic KernLib 30, if the requested maximum length is negative.
|
|
117 |
@panic KernLib 26, if the requested length is less than the length of any existing data.
|
|
118 |
*/
|
|
119 |
EXPORT_C HBuf8* HBuf8::ReAlloc(TInt aNewMax)
|
|
120 |
{
|
|
121 |
CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"HBuf8::ReAlloc");
|
|
122 |
__ASSERT_ALWAYS(aNewMax>=0,KL::Panic(KL::ETDes8MaxLengthNegative));
|
|
123 |
__ASSERT_ALWAYS(Length()<=aNewMax,KL::Panic(KL::ETDes8ReAllocTooSmall));
|
|
124 |
HBuf8* pNew=(HBuf8*)Kern::ReAlloc(this, aNewMax*sizeof(TUint8)+sizeof(TDes8) );
|
|
125 |
if(pNew)
|
|
126 |
pNew->iMaxLength=aNewMax;
|
|
127 |
return pNew;
|
|
128 |
}
|
|
129 |
|
|
130 |
|
|
131 |
/**
|
|
132 |
Copies the content of the source descriptor to the destination descriptor.
|
|
133 |
|
|
134 |
If the current thread is a user thread, i.e. the mode in spsr_svc is 'User',
|
|
135 |
then data is read using user mode privileges .
|
|
136 |
|
|
137 |
@param aDest The destination descriptor.
|
|
138 |
@param aSrc The source descriptor.
|
|
139 |
|
|
140 |
@panic KERN-COMMON 19, if aDest is not a valid descriptor type.
|
|
141 |
@panic KERN-COMMON 23, if aSrc is longer that the maximum length of aDest.
|
|
142 |
@panic KERN-EXEC 33, if aSrc is not a valid descriptor type.
|
|
143 |
|
|
144 |
@pre Do not call from User thread if in a critical section.
|
|
145 |
@pre Interrupts must be enabled.
|
|
146 |
@pre Kernel must be unlocked.
|
|
147 |
@pre No fast mutex can be held.
|
|
148 |
@pre Call in a thread context.
|
|
149 |
@pre Can be used in a device driver.
|
|
150 |
|
|
151 |
@post The length of the destination descriptor is equal to the length of the source descriptor.
|
|
152 |
*/
|
|
153 |
EXPORT_C void Kern::KUDesGet(TDes8& aDest, const TDesC8& aSrc)
|
|
154 |
{
|
|
155 |
CHECK_PRECONDITIONS(MASK_NO_CRITICAL_IF_USER|MASK_THREAD_STANDARD,"Kern::KUDesGet");
|
|
156 |
//ETDes8BadDescriptorType = 19
|
|
157 |
//ETDes8Overflow = 23
|
|
158 |
//EKUDesInfoInvalidType= 33
|
|
159 |
TInt ulen, umax;
|
|
160 |
TUint8* kptr=(TUint8*)aDest.Ptr();
|
|
161 |
const TUint8* uptr=Kern::KUDesInfo(aSrc, ulen, umax);
|
|
162 |
aDest.SetLength(ulen);
|
|
163 |
kumemget(kptr,uptr,ulen);
|
|
164 |
}
|
|
165 |
|
|
166 |
|
|
167 |
/**
|
|
168 |
Copies the content of the source descriptor to the destination descriptor.
|
|
169 |
|
|
170 |
If the current thread is a user thread, i.e. the mode in spsr_svc is 'User',
|
|
171 |
then data is written using user mode privileges.
|
|
172 |
|
|
173 |
@param aDest The destination descriptor.
|
|
174 |
@param aSrc The source descriptor.
|
|
175 |
|
|
176 |
@panic KERN-COMMON 19, if aSrc is not a valid descriptor type.
|
|
177 |
@panic KERN-EXEC 33, if aDest is not a valid descriptor type.
|
|
178 |
@panic KERN-EXEC 34, if aDest is not a modifiable descriptor type.
|
|
179 |
@panic KERN-EXEC 35, if aSrc is longer that the maximum length of aDest.
|
|
180 |
|
|
181 |
@pre Do not call from User thread if in a critical section.
|
|
182 |
@pre Interrupts must be enabled.
|
|
183 |
@pre Kernel must be unlocked.
|
|
184 |
@pre No fast mutex can be held.
|
|
185 |
@pre Call in a thread context.
|
|
186 |
@pre Can be used in a device driver.
|
|
187 |
|
|
188 |
@post The length of aDest is equal to the length of aSrc.
|
|
189 |
@post If aDest is a TPtr type then its maximum length is equal its new length.
|
|
190 |
*/
|
|
191 |
//ETDes8BadDescriptorType = 19
|
|
192 |
//EKUDesInfoInvalidType = 33
|
|
193 |
//EKUDesSetLengthInvalidType = 34
|
|
194 |
//EKUDesSetLengthOverflow = 35
|
|
195 |
EXPORT_C void Kern::KUDesPut(TDes8& aDest, const TDesC8& aSrc)
|
|
196 |
{
|
|
197 |
CHECK_PRECONDITIONS(MASK_NO_CRITICAL_IF_USER|MASK_THREAD_STANDARD,"Kern::KUDesPut");
|
|
198 |
TInt ulen, umax;
|
|
199 |
TInt klen=aSrc.Length();
|
|
200 |
const TUint8* kptr=aSrc.Ptr();
|
|
201 |
TUint8* uptr=(TUint8*)Kern::KUDesInfo(aDest, ulen, umax);
|
|
202 |
Kern::KUDesSetLength(aDest, klen);
|
|
203 |
kumemput(uptr,kptr,klen);
|
|
204 |
}
|
|
205 |
|
|
206 |
#ifndef __DES8_MACHINE_CODED__
|
|
207 |
|
|
208 |
|
|
209 |
/**
|
|
210 |
Gets information about the specified descriptor.
|
|
211 |
|
|
212 |
If the current thread is a user thread, i.e. if the mode in spsr_svc is 'User',
|
|
213 |
then the descriptor is read using user mode privileges.
|
|
214 |
|
|
215 |
@param aSrc The descriptor for which information is to be fetched.
|
|
216 |
@param aLength On return, set to the length of the descriptor.
|
|
217 |
@param aMaxLength On return, set to the maximum length of the descriptor,
|
|
218 |
or -1 if the descriptor is not writable.
|
|
219 |
|
|
220 |
@return Address of first byte in descriptor.
|
|
221 |
|
|
222 |
@panic KERN-EXEC 33, if aSrc is not a valid descriptor type.
|
|
223 |
|
|
224 |
@pre Do not call from User thread if in a critical section.
|
|
225 |
@pre Interrupts must be enabled.
|
|
226 |
@pre Kernel must be unlocked.
|
|
227 |
@pre No fast mutex can be held.
|
|
228 |
@pre Call in a thread context.
|
|
229 |
@pre Can be used in a device driver.
|
|
230 |
|
|
231 |
*/
|
|
232 |
EXPORT_C const TUint8* Kern::KUDesInfo(const TDesC8& aSrc, TInt& aLength, TInt& aMaxLength)
|
|
233 |
{
|
|
234 |
CHECK_PRECONDITIONS(MASK_NO_CRITICAL_IF_USER|MASK_THREAD_STANDARD,"Kern::KUDesInfo");
|
|
235 |
//EKUDesInfoInvalidType 33
|
|
236 |
TUint32 typelen;
|
|
237 |
kumemget32(&typelen,&aSrc,sizeof(typelen));
|
|
238 |
TInt type=typelen>>KShiftDesType;
|
|
239 |
aLength=typelen&KMaskDesLength;
|
|
240 |
aMaxLength=-1; // if descriptor not writeable
|
|
241 |
const TUint8* p=NULL;
|
|
242 |
const TAny** pA=(const TAny**)&aSrc;
|
|
243 |
switch(type)
|
|
244 |
{
|
|
245 |
case EBufC: p=(const TUint8*)(pA+1); return p;
|
|
246 |
case EPtrC: kumemget32(&p,pA+1,sizeof(TAny*)); return p;
|
|
247 |
case EPtr: kumemget32(&p,pA+2,sizeof(TAny*)); break;
|
|
248 |
case EBuf: p=(const TUint8*)(pA+2); break;
|
|
249 |
case EBufCPtr: kumemget32(&p,pA+2,sizeof(TAny*)); p+=sizeof(TDesC8); break;
|
|
250 |
default: K::PanicKernExec(EKUDesInfoInvalidType);
|
|
251 |
}
|
|
252 |
kumemget32(&aMaxLength,pA+1,sizeof(TInt));
|
|
253 |
return p;
|
|
254 |
}
|
|
255 |
|
|
256 |
|
|
257 |
/**
|
|
258 |
Sets the length of the specified descriptor.
|
|
259 |
|
|
260 |
If the current thread is a user thread, i.e. if the mode in spsr_svc is 'User',
|
|
261 |
then the length is written using user mode privileges.
|
|
262 |
|
|
263 |
@param aDes The descriptor.
|
|
264 |
@param aLength The new descriptor length.
|
|
265 |
|
|
266 |
@panic KERN-EXEC 34, if aDes is not a modifiable descriptor type.
|
|
267 |
@panic KERN-EXEC 35, if aLength is longer that the maximum length of aDes.
|
|
268 |
|
|
269 |
@pre Do not call from User thread if in a critical section.
|
|
270 |
@pre Interrupts must be enabled.
|
|
271 |
@pre Kernel must be unlocked.
|
|
272 |
@pre No fast mutex can be held.
|
|
273 |
@pre Call in a thread context.
|
|
274 |
@pre Can be used in a device driver.
|
|
275 |
|
|
276 |
@post The length of aDes is equal to aLength.
|
|
277 |
@post If aDes is a TPtr type then its maximum length is equal its new length.
|
|
278 |
*/
|
|
279 |
EXPORT_C void Kern::KUDesSetLength(TDes8& aDes, TInt aLength)
|
|
280 |
{
|
|
281 |
CHECK_PRECONDITIONS(MASK_NO_CRITICAL_IF_USER|MASK_THREAD_STANDARD,"Kern::KUDesSetLength");
|
|
282 |
//EKUDesSetLengthInvalidType=34
|
|
283 |
//EKUDesSetLengthOverflow=35
|
|
284 |
TUint32 deshdr[2];
|
|
285 |
kumemget32(deshdr,&aDes,sizeof(TDes8));
|
|
286 |
TInt type=deshdr[0]>>KShiftDesType;
|
|
287 |
if (type!=EPtr && type!=EBuf && type!=EBufCPtr)
|
|
288 |
K::PanicKernExec(EKUDesSetLengthInvalidType);
|
|
289 |
if ((TUint32)aLength>deshdr[1])
|
|
290 |
K::PanicKernExec(EKUDesSetLengthOverflow);
|
|
291 |
deshdr[0]=(TUint32(type)<<KShiftDesType)|aLength;
|
|
292 |
deshdr[1]=aLength;
|
|
293 |
kumemput32(&aDes,deshdr,sizeof(TUint32));
|
|
294 |
if (type==EBufCPtr)
|
|
295 |
{
|
|
296 |
TUint32 bufcptr;
|
|
297 |
kumemget32(&bufcptr,(&aDes)+1,sizeof(bufcptr));
|
|
298 |
kumemput32((TAny*)bufcptr,deshdr+1,sizeof(TUint32));
|
|
299 |
}
|
|
300 |
}
|
|
301 |
#endif
|
|
302 |
|
|
303 |
|
|
304 |
#ifndef __DES8_MACHINE_CODED__
|
|
305 |
/**
|
|
306 |
Checks whether the specified name is a valid Kernel-side object name.
|
|
307 |
|
|
308 |
A name is invalid, if it contains non-ascii characters, or any of
|
|
309 |
the three characters: "*", "?", ":".
|
|
310 |
|
|
311 |
@param aName The name to be checked.
|
|
312 |
|
|
313 |
@return KErrNone, if the name is valid; KErrBadName, if the name is invalid.
|
|
314 |
|
|
315 |
@pre Calling thread can be either in a critical section or not.
|
|
316 |
@pre Interrupts must be enabled.
|
|
317 |
@pre Kernel must be unlocked.
|
|
318 |
@pre No fast mutex can be held.
|
|
319 |
@pre Call in a thread context.
|
|
320 |
@pre Can be used in a device driver.
|
|
321 |
*/
|
|
322 |
#ifndef __KERNEL_MODE__
|
|
323 |
#error "TDesC is not 8-bit as __KERNEL_MODE__ is not defined (see e32cmn.h)"
|
|
324 |
#endif
|
|
325 |
EXPORT_C TInt Kern::ValidateName(const TDesC& aName)
|
|
326 |
{
|
|
327 |
CHECK_PRECONDITIONS(MASK_THREAD_STANDARD,"Kern::ValidateName");
|
|
328 |
TUint8* pName = const_cast<TUint8*>(aName.Ptr());
|
|
329 |
TInt pNameLen = aName.Length();
|
|
330 |
for(;pNameLen;pName++,pNameLen--)
|
|
331 |
if(*pName>0x7e || *pName<0x20 || *pName=='*' || *pName=='?' || *pName==':')
|
|
332 |
return KErrBadName;
|
|
333 |
return KErrNone;
|
|
334 |
}
|
|
335 |
|
|
336 |
extern "C" EXPORT_C TInt memicmp(const TAny* aLeft, const TAny* aRight, TUint aLength)
|
|
337 |
{
|
|
338 |
const TUint8* l = (const TUint8*) aLeft;
|
|
339 |
const TUint8* r = (const TUint8*) aRight;
|
|
340 |
while (aLength--)
|
|
341 |
{
|
|
342 |
TInt lc = *l++;
|
|
343 |
TInt rc = *r++;
|
|
344 |
if (lc>='A' && lc<='Z') lc += ('a'-'A');
|
|
345 |
if (rc>='A' && rc<='Z') rc += ('a'-'A');
|
|
346 |
lc -= rc;
|
|
347 |
if (lc)
|
|
348 |
return lc;
|
|
349 |
}
|
|
350 |
return 0;
|
|
351 |
}
|
|
352 |
#endif
|
|
353 |
|
|
354 |
#ifdef __DES8_MACHINE_CODED__
|
|
355 |
GLDEF_C void KUDesInfoPanicBadDesType()
|
|
356 |
{
|
|
357 |
K::PanicKernExec(EKUDesInfoInvalidType);
|
|
358 |
}
|
|
359 |
|
|
360 |
GLDEF_C void KUDesSetLengthPanicBadDesType()
|
|
361 |
{
|
|
362 |
K::PanicKernExec(EKUDesSetLengthInvalidType);
|
|
363 |
}
|
|
364 |
|
|
365 |
GLDEF_C void KUDesSetLengthPanicOverflow()
|
|
366 |
{
|
|
367 |
K::PanicKernExec(EKUDesSetLengthOverflow);
|
|
368 |
}
|
|
369 |
#endif
|