Все нормально листает Handle но на фукции NtQueryObject в services.exe виснет тут Код (Text): ::services.exe----------------------- 821CA540 0010 100020 2 2 1 1 File \Device\HarddiskVolume1\WINDOWS\system32 82250938 01e0 12019f 0 0 1 2 File \Device\NamedPipe\ntsvcs 815B8028 01e4 12019f 0 0 1 2 File \Device\NamedPipe\ntsvcs 81B35850 01ec 12019f 0 0 1 2 File \Device\NamedPipe\ntsvcs 81B0A820 020c 12019f 0 0 1 1 File \Device\NamedPipe\scerpc 81B58D38 0210 12019f 0 0 1 2 File \Device\NamedPipe\scerpc 81ACA2E0 0224 100001 0 0 1 1 File \Device\KsecDD 813CC5B0 0244 12019f 0 0 1 2 File \Device\NamedPipe\ntsvcs 81BF89E8 0250 1a019f 0 0 1 1 File \Device\NamedPipe\net\NtControlPipe1 81B39338 0268 12019f 0 0 1 1 File \Device\NamedPipe\ntsvcs 81AA8AA0 026c 12019f 0 0 1 3 File тут по идее должен быть "\Device\NamedPipe\net\NtControlPipe1" КОД: Код (Text): while (NtQuerySystemInformation(NT::SystemHandleInformation, p, n * sizeof (*p), &Ret) == STATUS_INFO_LENGTH_MISMATCH) delete [] p, p = new ULONG[n *= 2]; ProcList_Create(&Proc_List); NT::PSYSTEM_HANDLE_INFORMATION h = NT::PSYSTEM_HANDLE_INFORMATION(p); lplp=Proc_List.lpList; lplp=lplp->Next; for (ULONG PCount=0;PCount<Proc_List.dwCount;PCount++) { printf("::%s----------------------- \n",lplp->szName); for (ULONG i = 0; i < h->uCount; i++) { if(h->aSH[i].uIdProcess==lplp->dwID) { if (h->aSH[i].ObjectType==28)//File Object { hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, h->aSH[i].uIdProcess); if (hProcess==NULL) continue; NT::OBJECT_BASIC_INFORMATION obi; if (NT::NtDuplicateObject(hProcess, HANDLE(h->aSH[i].Handle), NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ATTRIBUTES) != STATUS_SUCCESS) continue; NT::NtQueryObject(hObject, NT::ObjectBasicInformation, &obi, sizeof obi, &n); printf("%p %04hx %6lx %2x %3lx %3ld %4ld ", h->aSH[i].pObject, h->aSH[i].Handle, h->aSH[i].GrantedAccess, int(h->aSH[i].Flags), obi.Attributes, obi.HandleCount - 1, obi.PointerCount - 2); n = obi.TypeInformationLength + 2; NT::POBJECT_TYPE_INFORMATION oti = NT::POBJECT_TYPE_INFORMATION(new CHAR[n]); rv = NT::NtQueryObject(hObject, NT::ObjectTypeInformation, oti, n, &n); if (NT_SUCCESS(rv)) printf("%-14.*ws ", oti[0].Name.Length / 2, oti[0].Name.Buffer); n = obi.NameInformationLength == 0 ? MAX_PATH * sizeof (WCHAR) : obi.NameInformationLength; NT::POBJECT_NAME_INFORMATION oni = NT::POBJECT_NAME_INFORMATION(new CHAR[n]); rv = NT::NtQueryObject(hObject, NT::ObjectNameInformation, oni, n, &n); if (NT_SUCCESS(rv)) printf("%.*ws", oni[0].Name.Length / 2, oni[0].Name.Buffer); printf("\n"); if (!(obi.Attributes&(0x02|0x01)))//для inheried and protected from close NT::NtClose(hObject); CloseHandle(hProcess); } } } lplp=lplp->Next;
Да к стати! а виснет (уходит в себя) при вызове rv = NT::NtQueryObject(hObject, NT::ObjectTypeInformation, oti, n, &n);
Обычно это случается, при попытке получения имени именованного пайпа по хендлу. Но, похоже при других операциях тоже. Вобщем, трабла в том, что если пайп синхронный, то все операции то ли в очередь ставятся, то ли одним потоком обрабатываются. И если пайп уже чего-то делает и эта операция не завершена, то попытка получить имя пайпа завесит поток, до тех пор, пока пайп не закончит незавершенную операцию, а это может продолжаться очень долго. Это известная трабла. Многие на эти грабли наступали, даже гуру. Например, если ProcessExplorer'ом попытаться редактнуть DACL у "\Device\NamedPipe\net\NtControlPipe1", то он тоже виснет. В аттаче прога. Там эта проблема решается созданием отдельного потока и его убийством. Но это зело плохое решение. Недавно ElicZ выложил ImgList. Код ещё руки не дошли посмотреть, то в ридми он пишет, что, вроде, нашел решение. http://www.anticracking.sk/ElicZ _231279434__Hmz.rar
Выбрал таки минутку, посмотрел. Я думал Радим что-нить дельное придумал, а там то же убийство потока. Правда, ещё стек освобождается, но это и так понятно.
Обычно это случается, при попытке получения имени именованного пайпа по хендлу. Но, похоже при других операциях тоже. Мне фраза понравилась В переводе на русский язык означает "кирдык тебе в любом случае" )))
Спасибо Four-F разобрался, это было к вопросу о чтении файла открытого в эксклюзивном доступе... Единственное что меня смущает это то что при выходе из программы она вешается да так что её таск манагер даже не удаляет, причём это происходит только под XP. А под 2003 сервером даже и не думает вешаться. Первый раз такое вижу... Что бы это могло быть? никаких вроде Эксепшенов нет...
Поток один ибо алгоритм всё тот же - прибитие потока Я проверил процесс начинает зависать когда прибивается хотя бы один поток с "мертвым" обращением к Пайпу.... В PE KeyedEvent=kernelObject\CritSecOutOfMemoryEvent 3 iocompletisoona .... Я выложил два файла 1. OpenE.exe <PATHNAME> - Открывает в эксулюзиве файл и лочит его. 2. CA.exe <Pathname1> <PathName2> - копирует до 65536 (моё ограничение) первых байт из <Pathname1> - в <PathName2> Если <PathName1> - открыт в эксклюзиве... Напомню процесс виснет только под XP, а под 2003 всё в порядке... _1436316470__Ca.zip
Я, точнее ProcessExplorer, вижу несколько потоков. Все они чего-то ждут в NtQueryObject. kernelObject\CritSecOutOfMemoryEvent тут, наверное, не при чём. Он во всех процессах открывается. Разбирайся. 1149859551__ca.gif
Я проверил это те самые потоки которые были завершены TerminateThread - ом и считались зависшими... вот код: Код (Text): ....... hThread=CreateThread (NULL,0,(LPTHREAD_START_ROUTINE)GetObjectName,&ON,0,&tid); if (WaitForSingleObject(hThread, 500) == WAIT_TIMEOUT) { TerminateThread (hThread, 0); } GetExitCodeThread(hThread,&n); CloseHandle(hThread); ..... А вот функция Код (Text): DWORD GetObjectName (POBJECT_NAME pon) { return NT::NtQueryObject(pon->hObject, NT::ObjectNameInformation, pon->oni, pon->MaxNameLenght, &pon->MaxNameLenght); } Может я неправильно его терминейтю? .... хотя "Терминатор" в 2003 срабатывает как надо а в XP видимо нет...
TerminateThread (hThread, 0); выполняется без ошибки.... Но может быть дело в этом? TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems: If the target thread owns a critical section, the critical section will not be released. If the target thread is allocating memory from the heap, the heap lock will not be released. If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent. If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL. Как это обойти?
Код (Text): THREAD 81478020 Cid 0624.08e4 Teb: 7ffaa000 Win32Thread: 00000000 WAIT: (Executive) KernelMode Non-Alertable <font color="red]81368fdc SynchronizationEvent</font><!--color--> Not impersonating DeviceMap e17c7008 Owning Process 80e4f950 Wait Start TickCount 740741 Elapsed Ticks: 681623 Context Switch Count 6 UserTime 00:00:00.0000 KernelTime 00:00:00.0000 Start Address kernel32!OpenConsoleW (0x77e802f4) Win32 Start Address 0x00401080 Stack Init ed689000 Current ed6889d8 Base ed689000 Limit ed686000 Call 0 Priority 12 BasePriority 8 PriorityDecrement 2 DecrementCount 16 ChildEBP RetAddr ed6889f0 804ea71c nt!KiSwapContext+0x2e (FPO: [EBP 0xed688a24] [0,0,4]) ed6889fc 804ea5a3 nt!KiSwapThread+0x44 (FPO: [0,0,2]) <font color="red]ed688a24 8054daf6 nt!KeWaitForSingleObject+0x1c0</font><!--color--> (FPO: [Non-Fpo]) ed688a50 805bcb2a nt!IopAcquireFileObjectLock+0x4c (FPO: [Non-Fpo]) ed688a90 80576de7 nt!IopQueryXxxInformation+0x46 (FPO: [Non-Fpo]) ed688ab0 805755fd nt!IoQueryFileInformation+0x19 (FPO: [Non-Fpo]) ed688b24 805756af nt!IopQueryNameInternal+0x1af (FPO: [Non-Fpo]) ed688b44 80575154 nt!IopQueryName+0x19 (FPO: [Non-Fpo]) ed688c5c 80553d84 nt!ObQueryNameString+0xa5 (FPO: [Non-Fpo]) ed688d48 804d4e91 nt!NtQueryObject+0x229 (FPO: [Non-Fpo]) ed688d48 7ffe0304 nt!KiSystemService+0xc4 (FPO: [0,0] TrapFrame @ ed688d64) 0130ffec 00000000 SharedUserData!SystemCallStub+0x4 (FPO: [0,0,0]) Глянул Kernel Debugger'ом. Все потоки ждут на событии (каждый на своём). Событие создает IopQueryXxxInformation, и шлет драйверу обслуживающему файл IRP_MJ_QUERY_INFORMATION. Потом начинает ждать. Вот тут они и висят. Что с этим делать, я не знаю.
Всё я решил эту проблему... Прежде чем обращаться к объекту файл я запрашиваю атриббуты его при создании и если &FILE_SEQUENTIAL_ONLY Хрен к нему мы обратимся.... Все зависоны прошли.....
если бы всё так просто было... NtQueryInformationFile(..., FileModeInformation) для пайпа тоже приводит к дидлоку