|
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 |