libraries/memoryaccess/MemoryAccess.cpp
changeset 90 ceac7084e2e5
parent 86 56b6ee983610
equal deleted inserted replaced
89:17bed177107f 90:ceac7084e2e5
    21 
    21 
    22 #include <fshell/common.mmh>
    22 #include <fshell/common.mmh>
    23 
    23 
    24 #ifdef FSHELL_DOBJECTIX_SUPPORT
    24 #ifdef FSHELL_DOBJECTIX_SUPPORT
    25 #include "dobject.h" // To pick up my defn of DObjectIx/DObjectIxNinePointOneHack
    25 #include "dobject.h" // To pick up my defn of DObjectIx/DObjectIxNinePointOneHack
       
    26 #else
       
    27 TBool ObjectIxContains(RObjectIx& aHandles, DObject* aObj);
    26 #endif
    28 #endif
    27 
    29 
    28 #include <e32cmn.h>
    30 #include <e32cmn.h>
    29 #include "memoryaccess.h"
    31 #include "memoryaccess.h"
    30 #include "PropertyAccess.h"
    32 #include "PropertyAccess.h"
  2112 	TBuf8<256> buf;
  2114 	TBuf8<256> buf;
  2113 	
  2115 	
  2114 	// Code adapted from ExecHandler::HandleInfo
  2116 	// Code adapted from ExecHandler::HandleInfo
  2115 	DObject* pO=(DObject*)aObj;
  2117 	DObject* pO=(DObject*)aObj;
  2116 	TInt r = KErrNone;
  2118 	TInt r = KErrNone;
  2117 	/*
       
  2118 	DThread& t = *iClient;
       
  2119 	//TInt r=K::OpenObjectFromHandle(aHandle,pO);
       
  2120 	//BEGIN this bit copied from K::OpenObjectFromHandle
       
  2121 	TInt r=KErrBadHandle;
       
  2122 	NKern::ThreadEnterCS();
       
  2123 	NKern::LockSystem();
       
  2124 	pO=t.ObjectFromHandle(aHandle);
       
  2125 	if (pO)
       
  2126 		r=pO->Open();
       
  2127 	NKern::UnlockSystem();
       
  2128 	if (r!=KErrNone)
       
  2129 		{
       
  2130 		pO=NULL;
       
  2131 		NKern::ThreadLeaveCS();
       
  2132 		}
       
  2133 	//END
       
  2134 	*/
       
  2135 
  2119 
  2136 	if (r==KErrNone)
  2120 	if (r==KErrNone)
  2137 		{
  2121 		{
  2138 		//DObjectIx::Wait(); //TOMSCI I can't call this frmo a device driver, why did the code I copied do it but none of the DMemoryAccess stuff that uses containers do it??
  2122 		//DObjectIx::Wait(); //TOMSCI I can't call this frmo a device driver, why did the code I copied do it but none of the DMemoryAccess stuff that uses containers do it??
  2139 		//DProcess* pCurrentProcess=TheCurrentThread->iOwningProcess;
       
  2140 		//hinfo.iNumOpenInThread=TheCurrentThread->iHandles->Count(pO);
       
  2141 		//hinfo.iNumOpenInProcess=pCurrentProcess->iHandles->Count(pO);
       
  2142 
  2123 
  2143 		DObjectCon* const * cons=Kern::Containers();
  2124 		DObjectCon* const * cons=Kern::Containers();
  2144 		DObjectCon& threads = *cons[EThread];
  2125 		DObjectCon& threads = *cons[EThread];
  2145 		threads.Wait();
  2126 		threads.Wait();
  2146 		TInt c=threads.Count();
  2127 		TInt c=threads.Count();
  2162 						}
  2143 						}
  2163 					else
  2144 					else
  2164 						{
  2145 						{
  2165 						buf.Append(idBuf);
  2146 						buf.Append(idBuf);
  2166 						}
  2147 						}
  2167 					//++hinfo.iNumThreads;
       
  2168 					//if (pT->iOwningProcess==pCurrentProcess)
       
  2169 					//	++hinfo.iNumOpenInProcess;
       
  2170 					}
  2148 					}
  2171 				}
  2149 				}
  2172 			}
  2150 			}
  2173 		threads.Signal();
  2151 		threads.Signal();
  2174 
  2152 
  2182 			if (handles) // maybe a nearly dead one hanging around
  2160 			if (handles) // maybe a nearly dead one hanging around
  2183 				{
  2161 				{
  2184 				TInt rr=((DObjectIxNinePointTwoHack*)handles)->At(pO);
  2162 				TInt rr=((DObjectIxNinePointTwoHack*)handles)->At(pO);
  2185 				if (rr!=KErrNotFound)
  2163 				if (rr!=KErrNotFound)
  2186 					{
  2164 					{
  2187 					//++hinfo.iNumProcesses;
       
  2188 					TPckgBuf<TUint> idBuf(pP->iId);
  2165 					TPckgBuf<TUint> idBuf(pP->iId);
  2189 					if (buf.Length() + idBuf.Length() >= buf.MaxLength())
  2166 					if (buf.Length() + idBuf.Length() >= buf.MaxLength())
  2190 						{
  2167 						{
  2191 						r = KErrOverflow;
  2168 						r = KErrOverflow;
  2192 						break;
  2169 						break;
  2197 						}
  2174 						}
  2198 					}
  2175 					}
  2199 				}
  2176 				}
  2200 			}
  2177 			}
  2201 		processes.Signal();
  2178 		processes.Signal();
  2202 		//DObjectIx::Signal();
       
  2203 
       
  2204 
       
  2205 		//DObjectIx::Signal();
       
  2206 		//pO->Close(NULL);
       
  2207 		//NKern::ThreadLeaveCS();
       
  2208 		}
  2179 		}
  2209 	
  2180 	
  2210 	TInt clientLen = Kern::ThreadGetDesMaxLength(iClient, aOwnersBuf);
  2181 	TInt clientLen = Kern::ThreadGetDesMaxLength(iClient, aOwnersBuf);
  2211 	if (clientLen < 0) return clientLen;
  2182 	if (clientLen < 0) return clientLen;
  2212 	TInt writeErr = Kern::ThreadDesWrite(iClient, aOwnersBuf, buf, 0, KTruncateToMaxLength, NULL);
  2183 	TInt writeErr = Kern::ThreadDesWrite(iClient, aOwnersBuf, buf, 0, KTruncateToMaxLength, NULL);
  2213 	if (writeErr) return writeErr;
  2184 	if (writeErr) return writeErr;
  2214 	return (clientLen < buf.Length()) ? KErrOverflow : r;
  2185 	return (clientLen < buf.Length()) ? KErrOverflow : r;
  2215 #else
  2186 #else
  2216 	return KErrNotSupported;
  2187 
       
  2188 #ifdef __HANDLES_USE_RW_SPIN_LOCK__
       
  2189 #error "Memoryaccess doesn't support rw spin locks in RObjectIx!"
  2217 #endif
  2190 #endif
       
  2191 
       
  2192 	TBuf8<512> buf;
       
  2193 	TInt r = KErrNone;
       
  2194 	DObject* object = (DObject*)aObj;
       
  2195 
       
  2196 	DObjectCon& threads = *Kern::Containers()[EThread];
       
  2197 	threads.Wait();
       
  2198 	TInt c=threads.Count();
       
  2199 	for (TInt i=0;i<c;i++)
       
  2200 		{
       
  2201 		DThread *pT=(DThread *)threads[i];
       
  2202 		if (ObjectIxContains(pT->iHandles, object))
       
  2203 			{
       
  2204 			TPckgBuf<TUint> idBuf(pT->iId);
       
  2205 			if (buf.Length() + idBuf.Length() > buf.MaxLength())
       
  2206 				{
       
  2207 				r = KErrOverflow;
       
  2208 				break;
       
  2209 				}
       
  2210 			else
       
  2211 				{
       
  2212 				buf.Append(idBuf);
       
  2213 				}
       
  2214 			
       
  2215 			}
       
  2216 		}
       
  2217 	threads.Signal();
       
  2218 
       
  2219 	DObjectCon& processes = *Kern::Containers()[EProcess];
       
  2220 	processes.Wait();
       
  2221 	c = processes.Count();
       
  2222 	for (TInt i = 0; i < c; i++)
       
  2223 		{
       
  2224 		DProcess* proc = (DProcess*)processes[i];
       
  2225 		if (ObjectIxContains(proc->iHandles, object))
       
  2226 			{
       
  2227 			TPckgBuf<TUint> idBuf(proc->iId);
       
  2228 			if (buf.Length() + idBuf.Length() > buf.MaxLength())
       
  2229 				{
       
  2230 				r = KErrOverflow;
       
  2231 				break;
       
  2232 				}
       
  2233 			else
       
  2234 				{
       
  2235 				buf.Append(idBuf);
       
  2236 				}
       
  2237 			}
       
  2238 		}
       
  2239 	processes.Signal();
       
  2240 
       
  2241 	TInt clientLen = Kern::ThreadGetDesMaxLength(iClient, aOwnersBuf);
       
  2242 	if (clientLen < 0) return clientLen;
       
  2243 	TInt writeErr = Kern::ThreadDesWrite(iClient, aOwnersBuf, buf, 0, KTruncateToMaxLength, NULL);
       
  2244 	if (writeErr) return writeErr;
       
  2245 	return (clientLen < buf.Length()) ? KErrOverflow : r;
       
  2246 
       
  2247 #endif // FSHELL_DOBJECTIX_SUPPORT
  2218 	}
  2248 	}
  2219 
  2249 
  2220 TInt DMemoryAccess::GetThreadHandles(TInt aThreadId, TAny* aHandlesBuf)
  2250 TInt DMemoryAccess::GetThreadHandles(TInt aThreadId, TAny* aHandlesBuf)
  2221 	{
  2251 	{
  2222 #ifdef FSHELL_DOBJECTIX_SUPPORT
  2252 	NKern::ThreadEnterCS();
  2223 	TInt maxLength = Kern::ThreadGetDesMaxLength(iClient, aHandlesBuf);
       
  2224 	TInt err = KErrNone;
       
  2225 
       
  2226 	DObjectCon* const * cons = Kern::Containers();
  2253 	DObjectCon* const * cons = Kern::Containers();
  2227 	DObjectCon& container = *cons[EThread];
  2254 	DObjectCon& container = *cons[EThread];
  2228 	container.Wait();
  2255 	container.Wait();
  2229 	NKern::ThreadEnterCS();
       
  2230 	DThread* thread = Kern::ThreadFromId(aThreadId);
  2256 	DThread* thread = Kern::ThreadFromId(aThreadId);
  2231 	//TOMSCI FIXME we don't increment thread's ref count
  2257 	if (thread && thread->Open() != KErrNone)
  2232 	NKern::ThreadLeaveCS();
  2258 		{
       
  2259 		thread = NULL;
       
  2260 		}
  2233 	container.Signal();
  2261 	container.Signal();
  2234 	if (thread == NULL) 
  2262 	if (thread == NULL) 
  2235 		{
  2263 		{
       
  2264 		NKern::ThreadLeaveCS();
  2236 		return KErrNotFound;
  2265 		return KErrNotFound;
  2237 		}
  2266 		}
  2238 
  2267 
       
  2268 #ifdef FSHELL_DOBJECTIX_SUPPORT
  2239 	// Note, this code is inherently dodgy because it doesn't claim DObjectIx::HandleMutex.
  2269 	// Note, this code is inherently dodgy because it doesn't claim DObjectIx::HandleMutex.
       
  2270 	TInt maxLength = Kern::ThreadGetDesMaxLength(iClient, aHandlesBuf);
       
  2271 	TInt err = KErrNone;
       
  2272 
  2240 	DObjectIxNinePointTwoHack* handles = (DObjectIxNinePointTwoHack*)thread->iHandles;
  2273 	DObjectIxNinePointTwoHack* handles = (DObjectIxNinePointTwoHack*)thread->iHandles;
  2241 	if (handles)
  2274 	if (handles)
  2242 		{
  2275 		{
  2243 		TInt offset = 0;
  2276 		TInt offset = 0;
  2244 
  2277 
  2264 					offset += sizeof(TAny*);
  2297 					offset += sizeof(TAny*);
  2265 					}
  2298 					}
  2266 				}
  2299 				}
  2267 			}
  2300 			}
  2268 		}
  2301 		}
  2269 
  2302 #else
  2270 	//TOMSCI What is this unlock doing here? TODO FIXME!!!
  2303 	
  2271 	NKern::UnlockSystem();
  2304 	TInt c = thread->iHandles.Count();
       
  2305 	HBuf8* buf = HBuf::New(c * sizeof(DObject*));
       
  2306 	TInt err = KErrNoMemory;
       
  2307 	if (buf)
       
  2308 		{
       
  2309 		DObject** ptr = (DObject**)buf->Ptr();
       
  2310 		NKern::LockSystem();
       
  2311 		c = Min(thread->iHandles.Count(), c); // In case it's changed
       
  2312 		buf->SetLength(c * sizeof(DObject*));
       
  2313 		for (TInt i = 0; i < c; i++)
       
  2314 			{
       
  2315 			ptr[i] = thread->iHandles[i];
       
  2316 			}
       
  2317 		NKern::UnlockSystem();
       
  2318 
       
  2319 		err = Kern::ThreadDesWrite(iClient, aHandlesBuf, *buf, 0);
       
  2320 		delete buf;
       
  2321 		}
       
  2322 	else
       
  2323 		{
       
  2324 		err = KErrNoMemory;
       
  2325 		}
       
  2326 #endif
       
  2327 
       
  2328 	thread->Close(NULL);
       
  2329 	NKern::ThreadLeaveCS();
  2272 	return err;
  2330 	return err;
  2273 #else
       
  2274 	return KErrNotSupported;
       
  2275 #endif
       
  2276 	}
  2331 	}
  2277 
  2332 
  2278 TInt DMemoryAccess::GetProcessHandles(TInt aProcessId, TAny* aHandlesBuf)
  2333 TInt DMemoryAccess::GetProcessHandles(TInt aProcessId, TAny* aHandlesBuf)
  2279 	{
  2334 	{
       
  2335 	NKern::ThreadEnterCS();
       
  2336 	DObjectCon* const * cons = Kern::Containers();
       
  2337 	DObjectCon& container = *cons[EProcess];
       
  2338 	container.Wait();
       
  2339 	DProcess* proc = Kern::ProcessFromId(aProcessId);
       
  2340 	if (proc && proc->Open() != KErrNone)
       
  2341 		{
       
  2342 		proc = NULL;
       
  2343 		}
       
  2344 	container.Signal();
       
  2345 	if (proc == NULL)
       
  2346 		{
       
  2347 		NKern::ThreadLeaveCS();
       
  2348 		return KErrNotFound;
       
  2349 		}
       
  2350 
  2280 #ifdef FSHELL_DOBJECTIX_SUPPORT
  2351 #ifdef FSHELL_DOBJECTIX_SUPPORT
  2281 	TInt maxLength = Kern::ThreadGetDesMaxLength(iClient, aHandlesBuf);
  2352 	TInt maxLength = Kern::ThreadGetDesMaxLength(iClient, aHandlesBuf);
  2282 	TInt err = KErrNone;
  2353 	TInt err = KErrNone;
  2283 
       
  2284 	DObjectCon* const * cons = Kern::Containers();
       
  2285 	DObjectCon& container = *cons[EProcess];
       
  2286 	container.Wait();
       
  2287 	NKern::ThreadEnterCS();
       
  2288 	DProcess* process = Kern::ProcessFromId(aProcessId);
       
  2289 	NKern::ThreadLeaveCS();
       
  2290 	container.Signal();
       
  2291 	if (process == NULL) 
       
  2292 		{
       
  2293 		return KErrNotFound;
       
  2294 		}
       
  2295 
  2354 
  2296 	// Note, this code is inherently dodgy because it doesn't claim DObjectIx::HandleMutex.
  2355 	// Note, this code is inherently dodgy because it doesn't claim DObjectIx::HandleMutex.
  2297 	DObjectIxNinePointTwoHack* handles = (DObjectIxNinePointTwoHack*)process->iHandles;
  2356 	DObjectIxNinePointTwoHack* handles = (DObjectIxNinePointTwoHack*)process->iHandles;
  2298 	if (handles)
  2357 	if (handles)
  2299 		{
  2358 		{
  2322 					}
  2381 					}
  2323 				}
  2382 				}
  2324 			}
  2383 			}
  2325 		}
  2384 		}
  2326 
  2385 
       
  2386 #else // new RObjectIx code
       
  2387 
       
  2388 	TInt c = proc->iHandles.Count();
       
  2389 	HBuf8* buf = HBuf::New(c * sizeof(DObject*));
       
  2390 	TInt err = KErrNoMemory;
       
  2391 	if (buf)
       
  2392 		{
       
  2393 		DObject** ptr = (DObject**)buf->Ptr();
       
  2394 		NKern::LockSystem();
       
  2395 		c = Min(proc->iHandles.Count(), c); // In case it's changed
       
  2396 		buf->SetLength(c * sizeof(DObject*));
       
  2397 		for (TInt i = 0; i < c; i++)
       
  2398 			{
       
  2399 			ptr[i] = proc->iHandles[i];
       
  2400 			}
       
  2401 		NKern::UnlockSystem();
       
  2402 
       
  2403 		err = Kern::ThreadDesWrite(iClient, aHandlesBuf, *buf, 0);
       
  2404 		delete buf;
       
  2405 		}
       
  2406 	else
       
  2407 		{
       
  2408 		err = KErrNoMemory;
       
  2409 		}
       
  2410 #endif // FSHELL_DOBJECTIX_SUPPORT
       
  2411 
       
  2412 	proc->Close(NULL);
       
  2413 	NKern::ThreadLeaveCS();
  2327 	return err;
  2414 	return err;
  2328 #else
       
  2329 	return KErrNotSupported;
       
  2330 #endif
       
  2331 	}
  2415 	}
  2332 
  2416 
  2333 TInt DMemoryAccess::SetCriticalFlags(TInt aThreadHandle, TUint aFlags)
  2417 TInt DMemoryAccess::SetCriticalFlags(TInt aThreadHandle, TUint aFlags)
  2334 	{
  2418 	{
  2335 	NKern::LockSystem();
  2419 	NKern::LockSystem();
  3111 		TInt err = Kern::ThreadDesWrite(iClient, iClientBreakpointNotifyPkg, aPkg, 0);
  3195 		TInt err = Kern::ThreadDesWrite(iClient, iClientBreakpointNotifyPkg, aPkg, 0);
  3112 		Kern::RequestComplete(iClient, stat, err);
  3196 		Kern::RequestComplete(iClient, stat, err);
  3113 		iClientBreakpointNotifyPkg = NULL;
  3197 		iClientBreakpointNotifyPkg = NULL;
  3114 		}
  3198 		}
  3115 	}
  3199 	}
       
  3200 
       
  3201 #ifndef FSHELL_DOBJECTIX_SUPPORT
       
  3202 
       
  3203 DObject* RObjectIx::operator[](TInt aIndex)
       
  3204 	{
       
  3205 	// Must be holding system lock (technically, the 'read' lock)
       
  3206 	DObject* obj = 0;
       
  3207 	SSlot* slot = iSlots + aIndex;
       
  3208 	obj = Occupant(slot);
       
  3209 	return obj;
       
  3210 	}
       
  3211 
       
  3212 TBool ObjectIxContains(RObjectIx& aHandles, DObject* aObj)
       
  3213 	{
       
  3214 	NKern::LockSystem();
       
  3215 	TInt c = aHandles.Count();
       
  3216 	for (TInt i = 0; i < c; i++)
       
  3217 		{
       
  3218 		if (aHandles[i] == aObj)
       
  3219 			{
       
  3220 			NKern::UnlockSystem();
       
  3221 			return ETrue;
       
  3222 			}
       
  3223 		}
       
  3224 	NKern::UnlockSystem();
       
  3225 	return EFalse;
       
  3226 	}
       
  3227 
       
  3228 #endif