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