diff -r 17bed177107f -r ceac7084e2e5 libraries/memoryaccess/MemoryAccess.cpp --- a/libraries/memoryaccess/MemoryAccess.cpp Tue Nov 30 11:11:58 2010 +0000 +++ b/libraries/memoryaccess/MemoryAccess.cpp Tue Dec 07 17:29:09 2010 +0000 @@ -23,6 +23,8 @@ #ifdef FSHELL_DOBJECTIX_SUPPORT #include "dobject.h" // To pick up my defn of DObjectIx/DObjectIxNinePointOneHack +#else +TBool ObjectIxContains(RObjectIx& aHandles, DObject* aObj); #endif #include @@ -2114,31 +2116,10 @@ // Code adapted from ExecHandler::HandleInfo DObject* pO=(DObject*)aObj; TInt r = KErrNone; - /* - DThread& t = *iClient; - //TInt r=K::OpenObjectFromHandle(aHandle,pO); - //BEGIN this bit copied from K::OpenObjectFromHandle - TInt r=KErrBadHandle; - NKern::ThreadEnterCS(); - NKern::LockSystem(); - pO=t.ObjectFromHandle(aHandle); - if (pO) - r=pO->Open(); - NKern::UnlockSystem(); - if (r!=KErrNone) - { - pO=NULL; - NKern::ThreadLeaveCS(); - } - //END - */ if (r==KErrNone) { //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?? - //DProcess* pCurrentProcess=TheCurrentThread->iOwningProcess; - //hinfo.iNumOpenInThread=TheCurrentThread->iHandles->Count(pO); - //hinfo.iNumOpenInProcess=pCurrentProcess->iHandles->Count(pO); DObjectCon* const * cons=Kern::Containers(); DObjectCon& threads = *cons[EThread]; @@ -2164,9 +2145,6 @@ { buf.Append(idBuf); } - //++hinfo.iNumThreads; - //if (pT->iOwningProcess==pCurrentProcess) - // ++hinfo.iNumOpenInProcess; } } } @@ -2184,7 +2162,6 @@ TInt rr=((DObjectIxNinePointTwoHack*)handles)->At(pO); if (rr!=KErrNotFound) { - //++hinfo.iNumProcesses; TPckgBuf idBuf(pP->iId); if (buf.Length() + idBuf.Length() >= buf.MaxLength()) { @@ -2199,12 +2176,6 @@ } } processes.Signal(); - //DObjectIx::Signal(); - - - //DObjectIx::Signal(); - //pO->Close(NULL); - //NKern::ThreadLeaveCS(); } TInt clientLen = Kern::ThreadGetDesMaxLength(iClient, aOwnersBuf); @@ -2213,30 +2184,92 @@ if (writeErr) return writeErr; return (clientLen < buf.Length()) ? KErrOverflow : r; #else - return KErrNotSupported; + +#ifdef __HANDLES_USE_RW_SPIN_LOCK__ +#error "Memoryaccess doesn't support rw spin locks in RObjectIx!" #endif + + TBuf8<512> buf; + TInt r = KErrNone; + DObject* object = (DObject*)aObj; + + DObjectCon& threads = *Kern::Containers()[EThread]; + threads.Wait(); + TInt c=threads.Count(); + for (TInt i=0;iiHandles, object)) + { + TPckgBuf idBuf(pT->iId); + if (buf.Length() + idBuf.Length() > buf.MaxLength()) + { + r = KErrOverflow; + break; + } + else + { + buf.Append(idBuf); + } + + } + } + threads.Signal(); + + DObjectCon& processes = *Kern::Containers()[EProcess]; + processes.Wait(); + c = processes.Count(); + for (TInt i = 0; i < c; i++) + { + DProcess* proc = (DProcess*)processes[i]; + if (ObjectIxContains(proc->iHandles, object)) + { + TPckgBuf idBuf(proc->iId); + if (buf.Length() + idBuf.Length() > buf.MaxLength()) + { + r = KErrOverflow; + break; + } + else + { + buf.Append(idBuf); + } + } + } + processes.Signal(); + + TInt clientLen = Kern::ThreadGetDesMaxLength(iClient, aOwnersBuf); + if (clientLen < 0) return clientLen; + TInt writeErr = Kern::ThreadDesWrite(iClient, aOwnersBuf, buf, 0, KTruncateToMaxLength, NULL); + if (writeErr) return writeErr; + return (clientLen < buf.Length()) ? KErrOverflow : r; + +#endif // FSHELL_DOBJECTIX_SUPPORT } TInt DMemoryAccess::GetThreadHandles(TInt aThreadId, TAny* aHandlesBuf) { -#ifdef FSHELL_DOBJECTIX_SUPPORT - TInt maxLength = Kern::ThreadGetDesMaxLength(iClient, aHandlesBuf); - TInt err = KErrNone; - + NKern::ThreadEnterCS(); DObjectCon* const * cons = Kern::Containers(); DObjectCon& container = *cons[EThread]; container.Wait(); - NKern::ThreadEnterCS(); DThread* thread = Kern::ThreadFromId(aThreadId); - //TOMSCI FIXME we don't increment thread's ref count - NKern::ThreadLeaveCS(); + if (thread && thread->Open() != KErrNone) + { + thread = NULL; + } container.Signal(); if (thread == NULL) { + NKern::ThreadLeaveCS(); return KErrNotFound; } +#ifdef FSHELL_DOBJECTIX_SUPPORT // Note, this code is inherently dodgy because it doesn't claim DObjectIx::HandleMutex. + TInt maxLength = Kern::ThreadGetDesMaxLength(iClient, aHandlesBuf); + TInt err = KErrNone; + DObjectIxNinePointTwoHack* handles = (DObjectIxNinePointTwoHack*)thread->iHandles; if (handles) { @@ -2266,33 +2299,59 @@ } } } +#else + + TInt c = thread->iHandles.Count(); + HBuf8* buf = HBuf::New(c * sizeof(DObject*)); + TInt err = KErrNoMemory; + if (buf) + { + DObject** ptr = (DObject**)buf->Ptr(); + NKern::LockSystem(); + c = Min(thread->iHandles.Count(), c); // In case it's changed + buf->SetLength(c * sizeof(DObject*)); + for (TInt i = 0; i < c; i++) + { + ptr[i] = thread->iHandles[i]; + } + NKern::UnlockSystem(); - //TOMSCI What is this unlock doing here? TODO FIXME!!! - NKern::UnlockSystem(); + err = Kern::ThreadDesWrite(iClient, aHandlesBuf, *buf, 0); + delete buf; + } + else + { + err = KErrNoMemory; + } +#endif + + thread->Close(NULL); + NKern::ThreadLeaveCS(); return err; -#else - return KErrNotSupported; -#endif } TInt DMemoryAccess::GetProcessHandles(TInt aProcessId, TAny* aHandlesBuf) { -#ifdef FSHELL_DOBJECTIX_SUPPORT - TInt maxLength = Kern::ThreadGetDesMaxLength(iClient, aHandlesBuf); - TInt err = KErrNone; - + NKern::ThreadEnterCS(); DObjectCon* const * cons = Kern::Containers(); DObjectCon& container = *cons[EProcess]; container.Wait(); - NKern::ThreadEnterCS(); - DProcess* process = Kern::ProcessFromId(aProcessId); - NKern::ThreadLeaveCS(); + DProcess* proc = Kern::ProcessFromId(aProcessId); + if (proc && proc->Open() != KErrNone) + { + proc = NULL; + } container.Signal(); - if (process == NULL) + if (proc == NULL) { + NKern::ThreadLeaveCS(); return KErrNotFound; } +#ifdef FSHELL_DOBJECTIX_SUPPORT + TInt maxLength = Kern::ThreadGetDesMaxLength(iClient, aHandlesBuf); + TInt err = KErrNone; + // Note, this code is inherently dodgy because it doesn't claim DObjectIx::HandleMutex. DObjectIxNinePointTwoHack* handles = (DObjectIxNinePointTwoHack*)process->iHandles; if (handles) @@ -2324,10 +2383,35 @@ } } +#else // new RObjectIx code + + TInt c = proc->iHandles.Count(); + HBuf8* buf = HBuf::New(c * sizeof(DObject*)); + TInt err = KErrNoMemory; + if (buf) + { + DObject** ptr = (DObject**)buf->Ptr(); + NKern::LockSystem(); + c = Min(proc->iHandles.Count(), c); // In case it's changed + buf->SetLength(c * sizeof(DObject*)); + for (TInt i = 0; i < c; i++) + { + ptr[i] = proc->iHandles[i]; + } + NKern::UnlockSystem(); + + err = Kern::ThreadDesWrite(iClient, aHandlesBuf, *buf, 0); + delete buf; + } + else + { + err = KErrNoMemory; + } +#endif // FSHELL_DOBJECTIX_SUPPORT + + proc->Close(NULL); + NKern::ThreadLeaveCS(); return err; -#else - return KErrNotSupported; -#endif } TInt DMemoryAccess::SetCriticalFlags(TInt aThreadHandle, TUint aFlags) @@ -3113,3 +3197,32 @@ iClientBreakpointNotifyPkg = NULL; } } + +#ifndef FSHELL_DOBJECTIX_SUPPORT + +DObject* RObjectIx::operator[](TInt aIndex) + { + // Must be holding system lock (technically, the 'read' lock) + DObject* obj = 0; + SSlot* slot = iSlots + aIndex; + obj = Occupant(slot); + return obj; + } + +TBool ObjectIxContains(RObjectIx& aHandles, DObject* aObj) + { + NKern::LockSystem(); + TInt c = aHandles.Count(); + for (TInt i = 0; i < c; i++) + { + if (aHandles[i] == aObj) + { + NKern::UnlockSystem(); + return ETrue; + } + } + NKern::UnlockSystem(); + return EFalse; + } + +#endif