Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

979 lines
29 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. This function contains the default ntsd debugger extensions
  6. Author:
  7. Revision History:
  8. --*/
  9. char * AccessMask[] = { "Delete", "ReadControl", "WriteDac", "WriteOwner",
  10. "Synch", "", "", "",
  11. "Sacl", "MaxAllowed", "", "",
  12. "GenericAll", "GenericExec", "GenericWrite", "GenericRead"};
  13. char * TokenRights[] = {"AssignPrimary", "Duplicate", "Impersonate", "Query",
  14. "QuerySource", "AdjustPriv", "AdjustGroup", "AdjustDef"};
  15. char * KeyRights[] = { "QueryValue", "SetValue", "CreateSubKey", "EnumSubKey",
  16. "Notify", "CreateLink", "", "" };
  17. char * EventRights[] = {"QueryState", "ModifyState" };
  18. char * MutantRights[]={ "QueryState" };
  19. char * SemaphoreRights[] = { "QueryState", "ModifyState" };
  20. char * TimerRights[] = {"QueryState", "ModifyState" };
  21. char * ProfileRights[]={"Control"};
  22. char * ProcessRights[]={"Terminate", "CreateThread", "", "VMOp",
  23. "VMRead", "VMWrite", "DupHandle", "CreateProcess",
  24. "SetQuota", "SetInfo", "QueryInfo", "SetPort" };
  25. char * ThreadRights[] ={"Terminate", "Suspend", "Alert", "GetContext",
  26. "SetContext", "SetInfo", "QueryInfo", "SetToken",
  27. "Impersonate", "DirectImpersonate" };
  28. char * SectionRights[]={"Query", "MapWrite", "MapRead", "MapExecute",
  29. "Extend"};
  30. char * FileRights[] = { "Read/List", "Write/Add", "Append/SubDir/CreatePipe", "ReadEA",
  31. "WriteEA", "Execute/Traverse", "DelChild", "ReadAttr",
  32. "WriteAttr"};
  33. char * PortRights[] = { "Connect" };
  34. char * DirRights[] = { "Query", "Traverse", "Create", "CreateSubdir" };
  35. char * SymLinkRights[]={"Query" };
  36. char * WinstaRights[]={ "EnumDesktops", "ReadAttr", "Clipboard", "CreateDesktop",
  37. "WriteAttr", "GlobalAtom", "ExitWindows", "",
  38. "Enumerate", "ReadScreen" };
  39. char * DesktopRights[]={"ReadObjects", "CreateWindow", "CreateMenu", "HookControl",
  40. "JournalRecord", "JournalPlayback", "Enumerate", "WriteObjects",
  41. "SwitchDesktop" };
  42. char * CompletionRights[] = { "Query", "Modify" };
  43. char * ChannelRights[] = { "ReadMessage", "WriteMessage", "Query", "SetInfo" };
  44. char * JobRights[] = { "AssignProcess", "SetAttr", "Query", "Terminate", "SetSecAttr" };
  45. TCHAR * PrivNames[] = {
  46. TEXT("Invalid"),
  47. TEXT("Invalid"),
  48. SE_CREATE_TOKEN_NAME,
  49. SE_ASSIGNPRIMARYTOKEN_NAME,
  50. SE_LOCK_MEMORY_NAME,
  51. SE_MACHINE_ACCOUNT_NAME,
  52. SE_TCB_NAME,
  53. SE_SECURITY_NAME,
  54. SE_TAKE_OWNERSHIP_NAME,
  55. SE_LOAD_DRIVER_NAME,
  56. SE_SYSTEM_PROFILE_NAME,
  57. SE_PROF_SINGLE_PROCESS_NAME,
  58. SE_INC_BASE_PRIORITY_NAME,
  59. SE_CREATE_PAGEFILE_NAME,
  60. SE_CREATE_PERMANENT_NAME,
  61. SE_BACKUP_NAME,
  62. SE_RESTORE_NAME,
  63. SE_SHUTDOWN_NAME,
  64. SE_DEBUG_NAME,
  65. SE_AUDIT_NAME,
  66. SE_SYSTEM_ENVIRONMENT_NAME,
  67. SE_CHANGE_NOTIFY_NAME,
  68. SE_REMOTE_SHUTDOWN_NAME,
  69. SE_UNDOCK_NAME,
  70. SE_SYNC_AGENT_NAME,
  71. SE_ENABLE_DELEGATION_NAME
  72. };
  73. ///////////////////////////////
  74. char * TokenImpLevels[] = { "Anonymous", "Identification", "Impersonation", "Delegation" };
  75. #define GetTokenImpersonationLevel( x ) \
  76. ( x <= SecurityDelegation ? TokenImpLevels[ x ] : "Invalid" )
  77. #define GHI_TYPE 0x00000001
  78. #define GHI_BASIC 0x00000002
  79. #define GHI_NAME 0x00000004
  80. #define GHI_SPECIFIC 0x00000008
  81. #define GHI_VERBOSE 0x00000010
  82. #define GHI_NOLOOKUP 0x00000020
  83. #define GHI_SILENT 0x00000100
  84. #define TYPE_NONE 0
  85. #define TYPE_EVENT 1
  86. #define TYPE_SECTION 2
  87. #define TYPE_FILE 3
  88. #define TYPE_PORT 4
  89. #define TYPE_DIRECTORY 5
  90. #define TYPE_LINK 6
  91. #define TYPE_MUTANT 7
  92. #define TYPE_WINSTA 8
  93. #define TYPE_SEM 9
  94. #define TYPE_KEY 10
  95. #define TYPE_TOKEN 11
  96. #define TYPE_PROCESS 12
  97. #define TYPE_THREAD 13
  98. #define TYPE_DESKTOP 14
  99. #define TYPE_COMPLETE 15
  100. #define TYPE_CHANNEL 16
  101. #define TYPE_TIMER 17
  102. #define TYPE_JOB 18
  103. #define TYPE_WPORT 19
  104. #define TYPE_MAX 20
  105. LPWSTR pszTypeNames[TYPE_MAX] = { L"None", L"Event", L"Section", L"File",
  106. L"Port", L"Directory", L"SymbolicLink",
  107. L"Mutant", L"WindowStation", L"Semaphore",
  108. L"Key", L"Token", L"Process", L"Thread",
  109. L"Desktop", L"IoCompletion", L"Channel",
  110. L"Timer", L"Job", L"WaitablePort" };
  111. LPSTR pszTypeNamesA[TYPE_MAX] = { "None", "Event", "Section", "File",
  112. "Port", "Directory", "SymbolicLink",
  113. "Mutant", "WindowStation", "Semaphore",
  114. "Key", "Token", "Process", "Thread",
  115. "Desktop", "IoCompletion", "Channe",
  116. "Timer", "Job", "WaitablePort" };
  117. typedef VOID
  118. ( * TYPEINFOFN)(HANDLE hObject, DWORD Flags);
  119. VOID EventInfo(HANDLE, ULONG);
  120. VOID MutantInfo(HANDLE, ULONG);
  121. VOID SemaphoreInfo(HANDLE, ULONG);
  122. VOID TimerInfo(HANDLE, ULONG);
  123. VOID SectionInfo(HANDLE, ULONG);
  124. VOID KeyInfo(HANDLE, ULONG);
  125. VOID ProcessInfo(HANDLE, ULONG);
  126. VOID ThreadInfo(HANDLE, ULONG);
  127. VOID TokenInfo(HANDLE, ULONG);
  128. VOID IoCompleteInfo(HANDLE, ULONG);
  129. VOID JobInfo( HANDLE, ULONG );
  130. typedef struct _TYPEINFO {
  131. PWSTR pszName;
  132. char * * AccessRights;
  133. DWORD NumberRights;
  134. TYPEINFOFN Func;
  135. } TYPEINFO, * PTYPEINFO;
  136. TYPEINFO TypeNames[TYPE_MAX] = {
  137. { L"None", NULL, 0, 0 },
  138. { L"Event", EventRights, 2, EventInfo },
  139. { L"Section", SectionRights, 5, SectionInfo },
  140. { L"File", FileRights, 9, 0 },
  141. { L"Port", PortRights, 1, 0 },
  142. { L"Directory", DirRights, 4, 0 },
  143. { L"SymbolicLink", SymLinkRights, 1, 0 },
  144. { L"Mutant", MutantRights, 2, MutantInfo },
  145. { L"WindowStation", WinstaRights, 10, 0 },
  146. { L"Semaphore", SemaphoreRights, 2, SemaphoreInfo },
  147. { L"Key", KeyRights, 6, KeyInfo },
  148. { L"Token", TokenRights, 8, TokenInfo },
  149. { L"Process", ProcessRights, 12, ProcessInfo },
  150. { L"Thread", ThreadRights, 10, ThreadInfo },
  151. { L"Desktop", DesktopRights, 10, 0 },
  152. { L"IoCompletion", CompletionRights, 2, IoCompleteInfo },
  153. { L"Channel", ChannelRights, 4, 0},
  154. { L"Timer", TimerRights, 2, TimerInfo },
  155. { L"Job", JobRights, 5, JobInfo },
  156. { L"WaitablePort", PortRights, 1, 0 }
  157. };
  158. void DisplayFlags( DWORD Flags,
  159. DWORD FlagLimit,
  160. char *flagset[],
  161. UCHAR * buffer)
  162. {
  163. char * offset;
  164. DWORD mask, test, i;
  165. DWORD scratch;
  166. if (!Flags) {
  167. strcpy((CHAR *)buffer, "None");
  168. return;
  169. }
  170. mask = 0;
  171. offset = (CHAR *) buffer;
  172. test = 1;
  173. for (i = 0 ; i < FlagLimit ; i++ ) {
  174. if (Flags & test) {
  175. scratch = sprintf(offset, "%s", flagset[i]);
  176. offset += scratch;
  177. mask |= test;
  178. if (Flags & (~mask)) {
  179. *offset++ = ',';
  180. }
  181. }
  182. test <<= 1;
  183. }
  184. }
  185. VOID
  186. EventInfo(
  187. HANDLE hEvent,
  188. DWORD Flags)
  189. {
  190. EVENT_BASIC_INFORMATION Info;
  191. NTSTATUS Status;
  192. Status = NtQueryEvent( hEvent,
  193. EventBasicInformation,
  194. &Info,
  195. sizeof( Info ),
  196. NULL );
  197. if (NT_SUCCESS( Status ) )
  198. {
  199. dprintf(" Event Type %s\n", Info.EventType == SynchronizationEvent ?
  200. "Auto Reset" : "Manual Reset" );
  201. dprintf(" Event is %s\n", Info.EventState ? "Set" : "Waiting" );
  202. }
  203. }
  204. VOID
  205. SemaphoreInfo(
  206. HANDLE hSem,
  207. DWORD Flags)
  208. {
  209. SEMAPHORE_BASIC_INFORMATION Info;
  210. NTSTATUS Status;
  211. Status = NtQuerySemaphore( hSem,
  212. SemaphoreBasicInformation,
  213. &Info,
  214. sizeof( Info ),
  215. NULL );
  216. if (NT_SUCCESS( Status ) )
  217. {
  218. dprintf(" Semaphore Count %d\n", Info.CurrentCount );
  219. dprintf(" Semaphore Limit %d\n", Info.MaximumCount );
  220. }
  221. }
  222. VOID
  223. MutantInfo(
  224. HANDLE hMutant,
  225. DWORD Flags)
  226. {
  227. MUTANT_BASIC_INFORMATION Info;
  228. NTSTATUS Status;
  229. Status = NtQueryMutant( hMutant,
  230. MutantBasicInformation,
  231. &Info,
  232. sizeof( Info ),
  233. NULL );
  234. if (NT_SUCCESS( Status ) )
  235. {
  236. dprintf(" Mutex is %s\n", Info.CurrentCount ? "Free" : "Owned" );
  237. if ( Info.AbandonedState )
  238. {
  239. dprintf(" Mutex is abandoned\n");
  240. }
  241. }
  242. }
  243. VOID
  244. TimerInfo(
  245. HANDLE hTimer,
  246. DWORD Flags)
  247. {
  248. TIMER_BASIC_INFORMATION Info;
  249. NTSTATUS Status;
  250. Status = NtQueryTimer( hTimer,
  251. TimerBasicInformation,
  252. &Info,
  253. sizeof( Info ),
  254. NULL );
  255. if (NT_SUCCESS( Status ) )
  256. {
  257. dprintf(" Timer is %s\n", Info.TimerState ? "signalled" : "waiting" );
  258. dprintf(" Remaining time %d\n", (DWORD) Info.RemainingTime.QuadPart );
  259. }
  260. }
  261. VOID
  262. SectionInfo(
  263. HANDLE hSection,
  264. DWORD Flags)
  265. {
  266. SECTION_BASIC_INFORMATION Info;
  267. NTSTATUS Status;
  268. Status = NtQuerySection( hSection,
  269. SectionBasicInformation,
  270. &Info,
  271. sizeof( Info ),
  272. NULL );
  273. if ( NT_SUCCESS( Status ) )
  274. {
  275. dprintf(" Section base address %#x\n", Info.BaseAddress );
  276. dprintf(" Section attributes %#x\n", Info.AllocationAttributes );
  277. dprintf(" Section max size %#x\n", (DWORD) Info.MaximumSize.QuadPart );
  278. }
  279. }
  280. VOID
  281. KeyInfo(
  282. HANDLE hKey,
  283. DWORD Flags)
  284. {
  285. PKEY_BASIC_INFORMATION pInfo;
  286. NTSTATUS Status;
  287. SYSTEMTIME st;
  288. FILETIME lft;
  289. ULONG Length;
  290. pInfo = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, 1024);
  291. if ( pInfo )
  292. {
  293. Status = NtQueryKey( hKey,
  294. KeyBasicInformation,
  295. pInfo,
  296. 1024,
  297. &Length );
  298. if ( NT_SUCCESS( Status ) )
  299. {
  300. FileTimeToLocalFileTime( (FILETIME *) &pInfo->LastWriteTime,
  301. & lft );
  302. FileTimeToSystemTime( &lft, &st );
  303. dprintf(" Key last write time: %02d:%02d:%02d. %d/%d/%d\n",
  304. st.wHour, st.wMinute, st.wSecond, st.wMonth,
  305. st.wDay, st.wYear );
  306. dprintf(" Key name %ws\n", pInfo->Name );
  307. }
  308. LocalFree( pInfo );
  309. }
  310. }
  311. VOID
  312. ProcessInfo(
  313. HANDLE hProcess,
  314. DWORD Flags)
  315. {
  316. PROCESS_BASIC_INFORMATION Info;
  317. NTSTATUS Status;
  318. Status = NtQueryInformationProcess( hProcess,
  319. ProcessBasicInformation,
  320. &Info,
  321. sizeof( Info ),
  322. NULL );
  323. if ( NT_SUCCESS( Status ) )
  324. {
  325. dprintf(" Process Id %d\n", Info.UniqueProcessId );
  326. dprintf(" Parent Process %d\n", Info.InheritedFromUniqueProcessId );
  327. dprintf(" Base Priority %d\n", Info.BasePriority );
  328. }
  329. }
  330. VOID
  331. ThreadInfo(
  332. HANDLE hThread,
  333. DWORD Flags)
  334. {
  335. THREAD_BASIC_INFORMATION Info;
  336. NTSTATUS Status;
  337. PVOID StartAddr ;
  338. CHAR Buffer[ 128 ];
  339. DWORD_PTR Offset ;
  340. Status = NtQueryInformationThread( hThread,
  341. ThreadBasicInformation,
  342. &Info,
  343. sizeof( Info ),
  344. NULL );
  345. if ( NT_SUCCESS( Status ) )
  346. {
  347. dprintf(" Thread Id %d.%d\n", Info.ClientId.UniqueProcess, Info.ClientId.UniqueThread );
  348. dprintf(" Priority %d\n", Info.Priority );
  349. dprintf(" Base Priority %d\n", Info.BasePriority );
  350. }
  351. Status = NtQueryInformationThread( hThread,
  352. ThreadQuerySetWin32StartAddress,
  353. &StartAddr,
  354. sizeof( PVOID ),
  355. NULL );
  356. if ( NT_SUCCESS( Status ) )
  357. {
  358. Buffer[0] = '\0';
  359. GetSymbol( StartAddr, Buffer, &Offset );
  360. dprintf(" Start Address %x %s\n",
  361. StartAddr, Buffer[0] ? Buffer : "" );
  362. }
  363. }
  364. VOID
  365. IoCompleteInfo(
  366. HANDLE hIoCompletionPort,
  367. DWORD Flags)
  368. {
  369. IO_COMPLETION_BASIC_INFORMATION Info;
  370. NTSTATUS Status;
  371. Status = NtQueryIoCompletion( hIoCompletionPort,
  372. IoCompletionBasicInformation,
  373. &Info,
  374. sizeof( Info ),
  375. NULL );
  376. if ( NT_SUCCESS( Status ) )
  377. {
  378. dprintf(" Depth %d\n", Info.Depth );
  379. }
  380. }
  381. VOID
  382. TokenInfo(
  383. HANDLE hToken,
  384. DWORD Flags)
  385. {
  386. TOKEN_STATISTICS Stats;
  387. UCHAR Buffer[ 1024 ];
  388. PTOKEN_USER pUser;
  389. PTOKEN_GROUPS pGroups;
  390. PTOKEN_PRIVILEGES pPrivs ;
  391. ULONG Size;
  392. NTSTATUS Status;
  393. UNICODE_STRING s;
  394. WCHAR Name[ 64 ];
  395. WCHAR Domain[ 64 ];
  396. DWORD NameSize;
  397. DWORD DomainSize;
  398. SID_NAME_USE Use;
  399. BOOL FoundName;
  400. ULONG Index;
  401. Status = NtQueryInformationToken( hToken,
  402. TokenStatistics,
  403. &Stats,
  404. sizeof(Stats),
  405. &Size );
  406. if ( NT_SUCCESS( Status ) )
  407. {
  408. dprintf(" Auth Id %#x : %#x\n", Stats.AuthenticationId.HighPart, Stats.AuthenticationId.LowPart );
  409. dprintf(" Type %s\n", Stats.TokenType == TokenPrimary ? "Primary" : "Impersonation" );
  410. dprintf(" Imp Level %s\n", GetTokenImpersonationLevel( Stats.ImpersonationLevel ) );
  411. if ( Flags & GHI_VERBOSE )
  412. {
  413. dprintf(" Token Id %#x : %#x \n", Stats.TokenId.HighPart, Stats.TokenId.LowPart );
  414. dprintf(" Mod Id %#x : %#x \n", Stats.ModifiedId.HighPart, Stats.ModifiedId.LowPart );
  415. dprintf(" Dyn Chg %#x\n", Stats.DynamicCharged );
  416. dprintf(" Dyn Avail %#x\n", Stats.DynamicAvailable );
  417. dprintf(" Groups %d\n", Stats.GroupCount );
  418. dprintf(" Privs %d\n", Stats.PrivilegeCount );
  419. pUser = (PTOKEN_USER) Buffer;
  420. Status = NtQueryInformationToken( hToken,
  421. TokenUser,
  422. Buffer,
  423. sizeof(Buffer),
  424. &Size );
  425. if (NT_SUCCESS( Status ) )
  426. {
  427. FoundName = FALSE ;
  428. if ( !(Flags & GHI_NOLOOKUP) )
  429. {
  430. NameSize = 64 ;
  431. DomainSize = 64 ;
  432. if ( LookupAccountSidW( NULL,
  433. pUser->User.Sid,
  434. Name,
  435. &NameSize,
  436. Domain,
  437. &DomainSize,
  438. &Use ) )
  439. {
  440. dprintf(" User %ws\\%ws\n", Domain, Name );
  441. FoundName = TRUE;
  442. }
  443. }
  444. if ( (Flags & GHI_NOLOOKUP) || (!FoundName) )
  445. {
  446. RtlConvertSidToUnicodeString( &s, pUser->User.Sid, TRUE );
  447. dprintf(" User %ws\n", s.Buffer );
  448. RtlFreeUnicodeString( &s );
  449. }
  450. }
  451. pGroups = (PTOKEN_GROUPS) Buffer;
  452. Status = NtQueryInformationToken( hToken,
  453. TokenGroups,
  454. Buffer,
  455. sizeof(Buffer),
  456. &Size );
  457. if ( NT_SUCCESS( Status ) )
  458. {
  459. dprintf(" Groups %d\n", pGroups->GroupCount );
  460. for ( Index = 0 ; Index < pGroups->GroupCount ; Index++ )
  461. {
  462. FoundName = FALSE ;
  463. if ( !(Flags & GHI_NOLOOKUP) )
  464. {
  465. NameSize = 64 ;
  466. DomainSize = 64 ;
  467. if ( LookupAccountSidW( NULL,
  468. pGroups->Groups[Index].Sid,
  469. Name,
  470. &NameSize,
  471. Domain,
  472. &DomainSize,
  473. &Use ) )
  474. {
  475. dprintf(" %ws\\%ws\n", Domain, Name );
  476. FoundName = TRUE;
  477. }
  478. }
  479. if ( ( Flags & GHI_NOLOOKUP ) || ( !FoundName ) )
  480. {
  481. RtlConvertSidToUnicodeString( &s,
  482. pGroups->Groups[Index].Sid,
  483. TRUE );
  484. dprintf(" %ws\n", s.Buffer );
  485. RtlFreeUnicodeString( &s );
  486. }
  487. }
  488. }
  489. pPrivs = (PTOKEN_PRIVILEGES) Buffer ;
  490. Status = NtQueryInformationToken( hToken,
  491. TokenPrivileges,
  492. Buffer,
  493. sizeof(Buffer),
  494. &Size );
  495. if ( NT_SUCCESS( Status ) )
  496. {
  497. dprintf(" Privileges %d\n", pPrivs->PrivilegeCount );
  498. for ( Index = 0 ; Index < pPrivs->PrivilegeCount ; Index++ )
  499. {
  500. dprintf(" %s (%s%s)\n",
  501. PrivNames[ pPrivs->Privileges[ Index ].Luid.LowPart ],
  502. pPrivs->Privileges[ Index ].Attributes & SE_PRIVILEGE_ENABLED ? " Enabled " : " ",
  503. pPrivs->Privileges[ Index ].Attributes & SE_PRIVILEGE_ENABLED_BY_DEFAULT ? "Default " : ""
  504. );
  505. }
  506. }
  507. }
  508. }
  509. }
  510. VOID
  511. JobInfo(
  512. HANDLE Job,
  513. ULONG Flags
  514. )
  515. {
  516. JOBOBJECT_BASIC_ACCOUNTING_INFORMATION BasicInfo ;
  517. UCHAR Buffer[ 128 * sizeof( ULONG_PTR ) ];
  518. PJOBOBJECT_BASIC_PROCESS_ID_LIST ProcList ;
  519. NTSTATUS Status ;
  520. ULONG Size ;
  521. TIME_FIELDS Time ;
  522. //
  523. // Delay load this API since it does not exist on NT 4
  524. //
  525. typedef NTSTATUS (NTAPI* PNTQUERYJOB)(HANDLE, JOBOBJECTINFOCLASS, PVOID, LONG, PULONG);
  526. HMODULE hNtdll;
  527. PNTQUERYJOB pNtQueryJob;
  528. hNtdll = GetModuleHandle( "ntdll.dll" );
  529. if (!hNtdll) {
  530. dprintf("Unable to get module handle for ntdll.dll\n");
  531. return;
  532. }
  533. pNtQueryJob =
  534. (PNTQUERYJOB)GetProcAddress( hNtdll, "NtQueryInformationJobObject" );
  535. if (pNtQueryJob == NULL) {
  536. dprintf("Unable to get address of NtQueryInformationJobObject\n");
  537. return;
  538. }
  539. Status = pNtQueryJob(
  540. Job,
  541. JobObjectBasicAccountingInformation,
  542. &BasicInfo,
  543. sizeof( BasicInfo ),
  544. &Size );
  545. if ( NT_SUCCESS( Status ) )
  546. {
  547. RtlTimeToElapsedTimeFields( &BasicInfo.TotalUserTime, &Time );
  548. dprintf( " TotalUserTime \t%3ld:%02ld:%02ld.%04ld\n",
  549. Time.Hour,
  550. Time.Minute,
  551. Time.Second,
  552. Time.Milliseconds );
  553. RtlTimeToElapsedTimeFields( &BasicInfo.TotalKernelTime, &Time );
  554. dprintf( " TotalKernelTime \t%3ld:%02ld:%02ld.%04ld\n",
  555. Time.Hour,
  556. Time.Minute,
  557. Time.Second,
  558. Time.Milliseconds );
  559. dprintf( " TotalProcesses \t%x\n",
  560. BasicInfo.TotalProcesses );
  561. dprintf( " ActiveProcesses \t%x\n",
  562. BasicInfo.ActiveProcesses );
  563. dprintf( " TotalPageFaultCount\t%x\n",
  564. BasicInfo.TotalPageFaultCount );
  565. if ( BasicInfo.ActiveProcesses )
  566. {
  567. ProcList = (PJOBOBJECT_BASIC_PROCESS_ID_LIST) Buffer ;
  568. Status = pNtQueryJob(
  569. Job,
  570. JobObjectBasicProcessIdList,
  571. ProcList,
  572. sizeof( Buffer ),
  573. &Size );
  574. if ( NT_SUCCESS( Status ) )
  575. {
  576. ULONG i ;
  577. dprintf( " Processes:\n" );
  578. for (i = 0 ; i < ProcList->NumberOfProcessIdsInList ; i++ )
  579. {
  580. dprintf( " %x\n", ProcList->ProcessIdList[ i ] );
  581. }
  582. }
  583. }
  584. }
  585. }
  586. DWORD
  587. GetObjectTypeIndex(
  588. LPCSTR pszTypeName )
  589. {
  590. WCHAR TypeName[ MAX_PATH ];
  591. DWORD i;
  592. mbstowcs( TypeName, pszTypeName, strlen( pszTypeName ) + 1 );
  593. for ( i = 1 ; i < TYPE_MAX ; i++ )
  594. {
  595. if (_wcsicmp( TypeNames[i].pszName, TypeName ) == 0 )
  596. {
  597. return( i );
  598. }
  599. }
  600. return( (DWORD) -1 );
  601. }
  602. DWORD
  603. GetHandleInfoDirect(
  604. HANDLE hProcess,
  605. HANDLE hThere,
  606. DWORD Flags,
  607. DWORD * Type)
  608. {
  609. HANDLE hHere;
  610. NTSTATUS Status;
  611. POBJECT_TYPE_INFORMATION pTypeInfo;
  612. POBJECT_NAME_INFORMATION pNameInfo;
  613. POBJECT_BASIC_INFORMATION pBasicInfo;
  614. UCHAR Buffer[1024];
  615. DWORD SuccessCount = 0;
  616. DWORD i;
  617. UCHAR szBuf[256];
  618. if (!DuplicateHandle( hProcess, hThere,
  619. GetCurrentProcess(), &hHere,
  620. 0, FALSE,
  621. DUPLICATE_SAME_ACCESS) )
  622. {
  623. if ( (Flags & GHI_SILENT) == 0)
  624. {
  625. dprintf("Could not duplicate handle %x, error %d\n",
  626. hThere, GetLastError() );
  627. }
  628. return( 0 );
  629. }
  630. pTypeInfo = (POBJECT_TYPE_INFORMATION) Buffer;
  631. pNameInfo = (POBJECT_NAME_INFORMATION) Buffer;
  632. pBasicInfo = (POBJECT_BASIC_INFORMATION) Buffer;
  633. if ( (Flags & GHI_SILENT) == 0)
  634. {
  635. dprintf("Handle %x\n", hThere );
  636. }
  637. if (Flags & GHI_TYPE)
  638. {
  639. ZeroMemory( Buffer, 1024 );
  640. Status = NtQueryObject( hHere, ObjectTypeInformation, pTypeInfo, 1024, NULL );
  641. if (NT_SUCCESS(Status))
  642. {
  643. if ((Flags & GHI_SILENT) == 0)
  644. {
  645. dprintf(" Type \t%ws\n", pTypeInfo->TypeName.Buffer );
  646. }
  647. for (i = 1; i < TYPE_MAX ; i++ )
  648. {
  649. if (wcscmp(pTypeInfo->TypeName.Buffer, TypeNames[i].pszName) == 0)
  650. {
  651. *Type = i;
  652. break;
  653. }
  654. }
  655. if (i == TYPE_MAX)
  656. {
  657. *Type = 0;
  658. }
  659. SuccessCount++;
  660. }
  661. }
  662. if (Flags & GHI_BASIC)
  663. {
  664. ZeroMemory( Buffer, 1024 );
  665. Status = NtQueryObject(hHere, ObjectBasicInformation, pBasicInfo,
  666. sizeof( OBJECT_BASIC_INFORMATION), NULL);
  667. if (NT_SUCCESS(Status))
  668. {
  669. dprintf(" Attributes \t%#x\n", pBasicInfo->Attributes );
  670. dprintf(" GrantedAccess\t%#x:\n", pBasicInfo->GrantedAccess );
  671. DisplayFlags( pBasicInfo->GrantedAccess >> 16,
  672. 16,
  673. AccessMask,
  674. szBuf);
  675. dprintf(" %s\n", szBuf);
  676. DisplayFlags( pBasicInfo->GrantedAccess & 0xFFFF,
  677. TypeNames[ *Type ].NumberRights,
  678. TypeNames[ *Type ].AccessRights,
  679. szBuf);
  680. dprintf(" %s\n", szBuf);
  681. dprintf(" HandleCount \t%d\n", pBasicInfo->HandleCount );
  682. dprintf(" PointerCount \t%d\n", pBasicInfo->PointerCount );
  683. SuccessCount++;
  684. }
  685. else
  686. {
  687. if ( Status != STATUS_INVALID_HANDLE )
  688. {
  689. dprintf("unable to query object information\n");
  690. }
  691. }
  692. }
  693. if ( (Flags & GHI_NAME) &&
  694. (*Type != TYPE_FILE ) )
  695. {
  696. ZeroMemory( Buffer, 1024 );
  697. Status = NtQueryObject( hHere, ObjectNameInformation, pNameInfo, 1024, NULL );
  698. if (NT_SUCCESS(Status))
  699. {
  700. dprintf(" Name \t%ws\n", pNameInfo->Name.Buffer ?
  701. pNameInfo->Name.Buffer : L"<none>" );
  702. SuccessCount++;
  703. }
  704. else
  705. {
  706. if ( Status != STATUS_INVALID_HANDLE )
  707. {
  708. dprintf("unable to query object information\n");
  709. }
  710. }
  711. }
  712. if ( Flags & GHI_SPECIFIC )
  713. {
  714. if ( TypeNames[ *Type ].Func )
  715. {
  716. dprintf(" Object Specific Information\n");
  717. TypeNames[ *Type ].Func( hHere, Flags );
  718. }
  719. }
  720. NtClose( hHere );
  721. return( SuccessCount );
  722. }
  723. DWORD
  724. GetHandleInfoInterface(
  725. HANDLE hThere,
  726. DWORD Flags,
  727. DWORD * Type)
  728. {
  729. ULONG64 IfHandle = (ULONG_PTR)hThere;
  730. HRESULT Status;
  731. DWORD SuccessCount = 0;
  732. DWORD i;
  733. UCHAR Buffer[1024];
  734. UCHAR szBuf[256];
  735. if ( (Flags & GHI_SILENT) == 0)
  736. {
  737. dprintf("Handle %I64x\n", IfHandle );
  738. }
  739. if (Flags & GHI_TYPE)
  740. {
  741. if (g_ExtData2->lpVtbl->
  742. ReadHandleData(g_ExtData2, IfHandle,
  743. DEBUG_HANDLE_DATA_TYPE_TYPE_NAME,
  744. Buffer, sizeof(Buffer), NULL) == S_OK)
  745. {
  746. if ((Flags & GHI_SILENT) == 0)
  747. {
  748. dprintf(" Type \t%s\n", Buffer);
  749. }
  750. for (i = 1; i < TYPE_MAX ; i++ )
  751. {
  752. if (strcmp((LPSTR)Buffer, pszTypeNamesA[i]) == 0)
  753. {
  754. *Type = i;
  755. break;
  756. }
  757. }
  758. if (i == TYPE_MAX)
  759. {
  760. *Type = 0;
  761. }
  762. SuccessCount++;
  763. }
  764. }
  765. if (Flags & GHI_BASIC)
  766. {
  767. DEBUG_HANDLE_DATA_BASIC Basic;
  768. if (g_ExtData2->lpVtbl->
  769. ReadHandleData(g_ExtData2, IfHandle,
  770. DEBUG_HANDLE_DATA_TYPE_BASIC,
  771. &Basic, sizeof(Basic), NULL) == S_OK)
  772. {
  773. dprintf(" Attributes \t%#x\n", Basic.Attributes );
  774. dprintf(" GrantedAccess\t%#x:\n", Basic.GrantedAccess );
  775. DisplayFlags( Basic.GrantedAccess >> 16,
  776. 16,
  777. AccessMask,
  778. szBuf);
  779. dprintf(" %s\n", szBuf);
  780. DisplayFlags( Basic.GrantedAccess & 0xFFFF,
  781. TypeNames[ *Type ].NumberRights,
  782. TypeNames[ *Type ].AccessRights,
  783. szBuf);
  784. dprintf(" %s\n", szBuf);
  785. dprintf(" HandleCount \t%d\n", Basic.HandleCount );
  786. dprintf(" PointerCount \t%d\n", Basic.PointerCount );
  787. SuccessCount++;
  788. }
  789. else
  790. {
  791. dprintf("unable to query object information\n");
  792. }
  793. }
  794. if ( (Flags & GHI_NAME) &&
  795. (*Type != TYPE_FILE ) )
  796. {
  797. if (g_ExtData2->lpVtbl->
  798. ReadHandleData(g_ExtData2, IfHandle,
  799. DEBUG_HANDLE_DATA_TYPE_OBJECT_NAME,
  800. Buffer, sizeof(Buffer), NULL) == S_OK)
  801. {
  802. dprintf(" Name \t%s\n",
  803. Buffer[0] ? Buffer : "<none>" );
  804. SuccessCount++;
  805. }
  806. else
  807. {
  808. dprintf("unable to query object information\n");
  809. }
  810. }
  811. if ( Flags & GHI_SPECIFIC )
  812. {
  813. dprintf(" No object specific information available\n");
  814. }
  815. return( SuccessCount );
  816. }
  817. DWORD
  818. GetHandleInfo(
  819. BOOL Direct,
  820. HANDLE hProcess,
  821. HANDLE hThere,
  822. DWORD Flags,
  823. DWORD * Type)
  824. {
  825. if (Direct) {
  826. return GetHandleInfoDirect(hProcess, hThere, Flags, Type);
  827. } else {
  828. return GetHandleInfoInterface(hThere, Flags, Type);
  829. }
  830. }