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.

1113 lines
36 KiB

  1. /*
  2. *
  3. * dump.cxx
  4. *
  5. * Routines for dumping data structures.
  6. *
  7. */
  8. #include "actdbg.hxx"
  9. //
  10. // Dumps a CBList containing CServerOxids
  11. //
  12. //
  13. void DumpBListSOxids(PNTSD_EXTENSION_APIS pExtApis,
  14. HANDLE hProcess,
  15. CBList* pblistoxids)
  16. {
  17. BOOL bStatus;
  18. DWORD i;
  19. PNTSD_OUTPUT_ROUTINE pfnPrint;
  20. pfnPrint = pExtApis->lpOutputRoutine;
  21. CServerOxid** poxids = (CServerOxid**)alloca(pblistoxids->_ulmaxData * sizeof(CServerOxid*));
  22. bStatus = ReadMemory(pExtApis, hProcess, (DWORD_PTR)pblistoxids->_data, (void*)poxids, pblistoxids->_ulmaxData * sizeof(CServerOxid*));
  23. if (!bStatus)
  24. return;
  25. CServerOxid* psoxid;
  26. psoxid = (CServerOxid*)alloca(sizeof(CServerOxid));
  27. (*pfnPrint)("\n");
  28. (*pfnPrint)(" CBList::_ulcElements 0x%x\n", pblistoxids->_ulcElements);
  29. (*pfnPrint)(" CBList::_ulmaxData 0x%x\n", pblistoxids->_ulmaxData);
  30. (*pfnPrint)(" CBList::_data 0x%x\n", pblistoxids->_data);
  31. (*pfnPrint)("\n");
  32. for (i = 0; i < pblistoxids->_ulmaxData; i++)
  33. {
  34. ZeroMemory(psoxid, sizeof(CServerOxid));
  35. // The valid entries in the list's array are not always in contiguous order.
  36. if (poxids[i])
  37. {
  38. bStatus = ReadMemory(pExtApis, hProcess, (DWORD_PTR)poxids[i], (void*)psoxid, sizeof(CServerOxid));
  39. if (!bStatus)
  40. {
  41. (*pfnPrint)("Failed to read memory for list element #%d\n", i);
  42. return;
  43. }
  44. (*pfnPrint)(" _pProcess 0x%x\n", psoxid->_pProcess);
  45. (*pfnPrint)(" _info (OXID_INFO)\n");
  46. (*pfnPrint)(" dwTid = %d\n", psoxid->_info.dwTid);
  47. (*pfnPrint)(" dwPid = %d\n", psoxid->_info.dwPid);
  48. (*pfnPrint)(" dwAuthnHint = %d\n", psoxid->_info.dwAuthnHint);
  49. (*pfnPrint)(" version (COMVERSION) MajorVersion=%d, MinorVersion=%d\n", psoxid->_info.version.MajorVersion, psoxid->_info.version.MinorVersion);
  50. (*pfnPrint)(" ipidRemUnknown ");
  51. DumpGuid(pExtApis, psoxid->_info.ipidRemUnknown);
  52. (*pfnPrint)("\n");
  53. (*pfnPrint)(" dwFlags 0x%x\n", psoxid->_info.dwFlags);
  54. (*pfnPrint)(" psa 0x%x", psoxid->_info.psa);
  55. if (psoxid->_info.psa)
  56. {
  57. (*pfnPrint)(" (run \"!rpcssext.dsa 0x%x\" to see contents)\n", psoxid->_info.psa);
  58. }
  59. (*pfnPrint)("\n");
  60. (*pfnPrint)(" _fApartment 0x%x\n", psoxid->_fApartment);
  61. (*pfnPrint)(" _fRunning 0x%x\n", psoxid->_fRunning);
  62. (*pfnPrint)("\n");
  63. }
  64. }
  65. (*pfnPrint)("\n");
  66. }
  67. //
  68. // Dumps the contents of a dualstringarray structure:
  69. //
  70. // wNumEntries -> # of elements in the array
  71. // wSecurityOffset -> points to the beginning of the security bindings within the array
  72. // aStringArray -> the actual bindings, in the following format
  73. //
  74. // (SB=StringBinding, SeB=SecurityBinding)
  75. //
  76. // [SB1]0[SB2]0...[SBn]00[SeB1]0[SeB2]0...[SeBn]00
  77. //
  78. // The shortest possible array has four entries, as follows:
  79. //
  80. // 0000
  81. //
  82. void DumpDUALSTRINGARRAY(
  83. PNTSD_EXTENSION_APIS pExtApis,
  84. HANDLE hProcess,
  85. DUALSTRINGARRAY* pdsa,
  86. char* pszPrefix) // for easier-to-read formatting
  87. {
  88. BOOL bStatus;
  89. BOOL bDone;
  90. DWORD dwcStringBindings = 0;
  91. DWORD dwcSecBindings = 0;
  92. PNTSD_OUTPUT_ROUTINE pfnPrint;
  93. pfnPrint = pExtApis->lpOutputRoutine;
  94. (*pfnPrint)("%swNumEntries 0x%x(%d)\n", pszPrefix, pdsa->wNumEntries, pdsa->wNumEntries);
  95. (*pfnPrint)("%swSecurityOffset 0x%x\n", pszPrefix, pdsa->wSecurityOffset);
  96. (*pfnPrint)("%sString bindings:\n", pszPrefix);
  97. USHORT* pCurrent;
  98. USHORT* pStart;
  99. pStart = pCurrent = &(pdsa->aStringArray[0]);
  100. bDone = FALSE;
  101. while (!bDone)
  102. {
  103. while (*pCurrent != 0)
  104. {
  105. pCurrent++;
  106. }
  107. if (*(pCurrent+1) == 0) // double zero, end of string bindings
  108. {
  109. bDone = TRUE;
  110. }
  111. if (pStart != pCurrent)
  112. {
  113. dwcStringBindings++;
  114. STRINGBINDING* psb = (STRINGBINDING*)pStart;
  115. (*pfnPrint)("%s wTowerId 0x%x, aNetworkAddr=%S\n", pszPrefix, psb->wTowerId, &(psb->aNetworkAddr));
  116. }
  117. pCurrent++;
  118. pStart = pCurrent;
  119. }
  120. if (dwcStringBindings == 0)
  121. {
  122. (*pfnPrint)("%s <no string bindings were present>\n", pszPrefix);
  123. }
  124. pCurrent++;
  125. pStart = pCurrent;
  126. (*pfnPrint)("%sSecurity bindings:\n", pszPrefix);
  127. bDone = FALSE;
  128. if (!bDone)
  129. {
  130. while (*pCurrent != 0)
  131. {
  132. pCurrent++;
  133. }
  134. if (*(pCurrent+1) == 0) // double zero, end of security bindings
  135. {
  136. bDone = TRUE;
  137. }
  138. if (pStart != pCurrent)
  139. {
  140. dwcSecBindings++;
  141. SECURITYBINDING* pseb = (SECURITYBINDING*)pStart;
  142. (*pfnPrint)("%s wAuthnSvc 0x%x, wAuthzSvc 0x%x, aPrincName=%S\n",
  143. pszPrefix,
  144. pseb->wAuthnSvc,
  145. pseb->wAuthzSvc,
  146. &(pseb->aPrincName));
  147. }
  148. pCurrent++;
  149. pStart = pCurrent;
  150. }
  151. if (dwcSecBindings == 0)
  152. {
  153. (*pfnPrint)("%s <no security bindings were present>\n", pszPrefix);
  154. }
  155. (*pfnPrint)("\n");
  156. return;
  157. }
  158. void
  159. DumpGuid(
  160. PNTSD_EXTENSION_APIS pExtApis,
  161. GUID & Guid
  162. )
  163. {
  164. PNTSD_OUTPUT_ROUTINE pfnPrint;
  165. pfnPrint = pExtApis->lpOutputRoutine;
  166. (*pfnPrint)( "{%8.8x-", Guid.Data1 );
  167. (*pfnPrint)( "%4.4x-", Guid.Data2 );
  168. (*pfnPrint)( "%4.4x-", Guid.Data3 );
  169. (*pfnPrint)( "%2.2x", Guid.Data4[0] );
  170. (*pfnPrint)( "%2.2x-", Guid.Data4[1] );
  171. (*pfnPrint)( "%2.2x", Guid.Data4[2] );
  172. (*pfnPrint)( "%2.2x", Guid.Data4[3] );
  173. (*pfnPrint)( "%2.2x", Guid.Data4[4] );
  174. (*pfnPrint)( "%2.2x", Guid.Data4[5] );
  175. (*pfnPrint)( "%2.2x", Guid.Data4[6] );
  176. (*pfnPrint)( "%2.2x}", Guid.Data4[7] );
  177. }
  178. void
  179. DumpActivationParams(
  180. PNTSD_EXTENSION_APIS pExtApis,
  181. HANDLE hProcess,
  182. ACTIVATION_PARAMS * pActParams
  183. )
  184. {
  185. PNTSD_OUTPUT_ROUTINE pfnPrint;
  186. WCHAR String[256];
  187. GUID Guid;
  188. BOOL bStatus;
  189. pfnPrint = pExtApis->lpOutputRoutine;
  190. pfnPrint( " hRpc\t\t\t0x%x\n", pActParams->hRpc );
  191. pfnPrint( " ProcessSignature\t0x%p\n", pActParams->ProcessSignature );
  192. pfnPrint( " pProcess\t\t0x%x\n", pActParams->pProcess );
  193. pfnPrint( " pToken\t\t0x%x\n", pActParams->pToken );
  194. pfnPrint( " pAuthInfo\t\t0x%x\n", pActParams->pAuthInfo );
  195. // UnsecureActivation
  196. pfnPrint( " MsgType\t\t%d ", pActParams->MsgType );
  197. switch ( pActParams->MsgType )
  198. {
  199. case GETCLASSOBJECT :
  200. pfnPrint( "(GetClassObject)\n" );
  201. break;
  202. case CREATEINSTANCE :
  203. pfnPrint( "(CreateInstance)\n" );
  204. break;
  205. case GETPERSISTENTINSTANCE :
  206. pfnPrint( "(GetPersistentInstance)\n" );
  207. break;
  208. default :
  209. pfnPrint( "(Invalid MsgType, bad ACTIVATION_PARAMS?)\n" );
  210. break;
  211. }
  212. pfnPrint( " Clsid\t\t\t0x%x " );
  213. DumpGuid( pExtApis, pActParams->Clsid );
  214. pfnPrint( "\n" );
  215. pfnPrint( " pwszServer\t\t0x%x", pActParams->pwszServer );
  216. if ( pActParams->pwszServer )
  217. {
  218. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pActParams->pwszServer, (void *)String, sizeof(String) );
  219. if ( bStatus )
  220. pfnPrint( " %S", String );
  221. }
  222. pfnPrint( "\n" );
  223. pfnPrint( " pwszWinstaDesktop\t0x%x", pActParams->pwszWinstaDesktop );
  224. if ( pActParams->pwszWinstaDesktop )
  225. {
  226. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pActParams->pwszWinstaDesktop, (void *)String, sizeof(String) );
  227. if ( bStatus )
  228. pfnPrint( " %S", String );
  229. }
  230. pfnPrint( "\n" );
  231. pfnPrint( " EnvBlock\t\t0x%x\n", pActParams->pEnvBlock );
  232. pfnPrint( " ClsContext\t\t0x%x\n", pActParams->ClsContext );
  233. pfnPrint( " dwPID \t\t0x%x (%d)\n", pActParams->dwPID);
  234. pfnPrint( " dwProcReqType\t\t%d ->", pActParams->dwProcessReqType);
  235. switch(pActParams->dwProcessReqType)
  236. {
  237. case PRT_IGNORE: pfnPrint("PRT_IGNORE\n"); break;
  238. case PRT_CREATE_NEW: pfnPrint("PRT_CREATE_NEW\n"); break;
  239. case PRT_USE_THIS: pfnPrint("PRT_USE_THIS\n"); break;
  240. case PRT_USE_THIS_ONLY: pfnPrint("PRT_USE_THIS_ONLY\n"); break;
  241. default:
  242. pfnPrint(" !ERROR! Unknown process request type!\n");
  243. }
  244. pfnPrint( " RemoteActivation\t%s\n", pActParams->RemoteActivation ? "TRUE" : "FALSE" );
  245. pfnPrint( " Interfaces\t\t%d\n", pActParams->Interfaces );
  246. pfnPrint( " pIIDs\t\t\t0x%x ", pActParams->pIIDs );
  247. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pActParams->pIIDs, (void *)&Guid, sizeof(Guid) );
  248. if ( bStatus )
  249. DumpGuid( pExtApis, Guid );
  250. pfnPrint( "\n" );
  251. pfnPrint( " pwszPath\t\t0x%x", pActParams->pwszPath );
  252. if ( pActParams->pwszPath )
  253. {
  254. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pActParams->pwszPath, (void *)String, sizeof(String) );
  255. if ( bStatus )
  256. pfnPrint( " %S", String );
  257. }
  258. pfnPrint( "\n" );
  259. pfnPrint( " pIFDStorage\t\t0x%x\n", pActParams->pIFDStorage );
  260. pfnPrint( " pIFDROT\t\t0x%x\n", pActParams->pIFDROT );
  261. pfnPrint( " Apartment\t\t0x%x\n", pActParams->Apartment );
  262. pfnPrint( " pOxidServer\t\t0x%x\n", pActParams->pOxidServer );
  263. pfnPrint( " ppServerORBindings\t\t0x%x\n", pActParams->ppServerORBindings );
  264. pfnPrint( " pOxidInfo\t\t0x%x\n", pActParams->pOxidInfo );
  265. pfnPrint( " pLocalMidOfRemote\t\t0x%x\n", pActParams->pLocalMidOfRemote );
  266. pfnPrint( " ProtseqId\t\t%d\n", pActParams->ProtseqId );
  267. pfnPrint( " FoundInROT\t\t%s\n", pActParams->FoundInROT ? "TRUE" : "FALSE" );
  268. pfnPrint( " ppIFD\t\t\t0x%x\n", pActParams->ppIFD );
  269. pfnPrint( " pResults\t\t0x%x\n", pActParams->pResults );
  270. pfnPrint( " fComPlusOnly\t\t%s\n", pActParams->fComplusOnly ? "TRUE" : "FALSE");
  271. pfnPrint( " pActPropsIn\t\t0x%x\n", pActParams->pActPropsIn);
  272. pfnPrint( " pActPropsOut\t\t0x%x\n", pActParams->pActPropsOut);
  273. pfnPrint( " pInstantiationInfo\t\t0x%x\n", pActParams->pInstantiationInfo);
  274. pfnPrint( " pInstanceInfo\t\t0x%x\n", pActParams->pInstanceInfo);
  275. pfnPrint( " pInScmResolverInfo\t\t0x%x\n", pActParams->pInScmResolverInfo);
  276. pfnPrint( " oldActivationCall\t\t%s\n", pActParams->oldActivationCall ? "TRUE" : "FALSE");
  277. pfnPrint( " activatedRemote\t\t%s\n", pActParams->activatedRemote ? "TRUE" : "FALSE");
  278. pfnPrint( " IsLocalOxid\t\t%s\n", pActParams->IsLocalOxid ? "TRUE" : "FALSE");
  279. pfnPrint( "\n" );
  280. }
  281. void
  282. DumpSecurityDescriptor(
  283. PNTSD_EXTENSION_APIS pExtApis,
  284. HANDLE hProcess,
  285. SECURITY_DESCRIPTOR * pSD
  286. )
  287. {
  288. const ACCT_DOM_NAME_SIZE = 64;
  289. PNTSD_OUTPUT_ROUTINE pfnPrint;
  290. PACL pDacl;
  291. ACL AclHeader;
  292. ACCESS_ALLOWED_ACE * pAce = NULL;
  293. WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
  294. DWORD cchComputer = MAX_COMPUTERNAME_LENGTH + 1;
  295. WCHAR AccountName[ACCT_DOM_NAME_SIZE];
  296. DWORD cchAccount = ACCT_DOM_NAME_SIZE;
  297. WCHAR DomainName[ACCT_DOM_NAME_SIZE];
  298. DWORD cchDomain = ACCT_DOM_NAME_SIZE;
  299. SID_NAME_USE SidNameType;
  300. BOOL bStatus;
  301. pfnPrint = pExtApis->lpOutputRoutine;
  302. pDacl = 0;
  303. if ( ! (pSD->Control & SE_DACL_PRESENT) || (0 == pSD->Dacl) )
  304. {
  305. (*pfnPrint)( "Security Descriptor has no discretionary ACL. Everyone allowed access.\n" );
  306. }
  307. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pSD->Dacl, (void *)&AclHeader, sizeof(AclHeader) );
  308. if ( ! bStatus )
  309. return;
  310. pDacl = (PACL) Alloc( AclHeader.AclSize );
  311. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pSD->Dacl, (void *)pDacl, AclHeader.AclSize );
  312. if ( ! bStatus )
  313. {
  314. (*pfnPrint)( "Couldn't read Dacl at 0x%x\n", pSD->Dacl );
  315. return;
  316. }
  317. (*pfnPrint)( " Dacl at 0x%x\n", pSD->Dacl );
  318. (void) GetComputerNameW( ComputerName, &cchComputer );
  319. for ( USHORT Index = 0; Index < pDacl->AceCount; Index++ )
  320. {
  321. if ( ! GetAce( pDacl, Index, (void **) &pAce ) )
  322. break;
  323. if ( (pAce->Header.AceType != ACCESS_ALLOWED_ACE_TYPE) &&
  324. (pAce->Header.AceType != ACCESS_DENIED_ACE_TYPE) )
  325. continue;
  326. cchAccount = ACCT_DOM_NAME_SIZE;
  327. cchDomain = ACCT_DOM_NAME_SIZE;
  328. bStatus = LookupAccountSidW(
  329. NULL,
  330. (PSID)&pAce->SidStart,
  331. AccountName,
  332. &cchAccount,
  333. DomainName,
  334. &cchDomain,
  335. &SidNameType );
  336. (*pfnPrint)( " ACE %d ", Index );
  337. if ( bStatus )
  338. {
  339. if ( DomainName[0] != 0 )
  340. {
  341. if ( lstrcmpiW( DomainName, L"BUILTIN" ) != 0 )
  342. (*pfnPrint)( "%s\\", DomainName );
  343. else
  344. (*pfnPrint)( "%s\\", ComputerName );
  345. }
  346. (*pfnPrint)( "%s ", AccountName );
  347. }
  348. else
  349. {
  350. (*pfnPrint)( "[couldn't get account name] " );
  351. }
  352. if ( ACCESS_ALLOWED_ACE_TYPE == pAce->Header.AceType )
  353. (*pfnPrint)( "Allowed " );
  354. else
  355. (*pfnPrint)( "Denied " );
  356. if ( pAce->Mask & COM_RIGHTS_EXECUTE )
  357. (*pfnPrint)( "DCOM Launch\n" );
  358. else
  359. (*pfnPrint)( "ACCESS_MASK 0x%x (ntseapi.h)", pAce->Mask );
  360. }
  361. Free( pDacl );
  362. }
  363. void
  364. DumpClsid(
  365. PNTSD_EXTENSION_APIS pExtApis,
  366. HANDLE hProcess,
  367. CClsidData * pClsidData
  368. )
  369. {
  370. PNTSD_OUTPUT_ROUTINE pfnPrint;
  371. CAppidData * pAppidData = NULL;
  372. WCHAR String[256];
  373. BOOL bStatus;
  374. pfnPrint = pExtApis->lpOutputRoutine;
  375. (*pfnPrint)( " " );
  376. DumpGuid( pExtApis, pClsidData->_Clsid );
  377. (*pfnPrint)( "\n" );
  378. (*pfnPrint)( " _pAppid 0x%x\n", pClsidData->_pAppid );
  379. (*pfnPrint)( " _pToken 0x%x\n", pClsidData->_pToken );
  380. (*pfnPrint)( " _ServerType %d ", pClsidData->_ServerType );
  381. switch ( pClsidData->_ServerType )
  382. {
  383. case SERVERTYPE_EXE32 :
  384. (*pfnPrint)( "LocalServer32\n" );
  385. break;
  386. case SERVERTYPE_SERVICE :
  387. (*pfnPrint)( "Service\n" );
  388. break;
  389. case SERVERTYPE_SURROGATE :
  390. (*pfnPrint)( "DLL in Surrogate\n" );
  391. break;
  392. case SERVERTYPE_EXE16 :
  393. (*pfnPrint)( "LocalServer (16bit)\n" );
  394. break;
  395. }
  396. (*pfnPrint)( " _pwszServer 0x%x", pClsidData->_pwszServer );
  397. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pClsidData->_pwszServer, (void *)String, sizeof(String) );
  398. if ( bStatus )
  399. pfnPrint( " %S", String );
  400. (*pfnPrint)( "\n" );
  401. (*pfnPrint)( " _pwszDarwinId 0x%x", pClsidData->_pwszDarwinId );
  402. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pClsidData->_pwszDarwinId, (void *)String, sizeof(String) );
  403. if ( bStatus )
  404. pfnPrint( " %S", String );
  405. (*pfnPrint)( "\n" );
  406. pAppidData = 0;
  407. if ( pClsidData->_pAppid )
  408. {
  409. pAppidData = (CAppidData *) Alloc( sizeof(CAppidData) );
  410. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pClsidData->_pAppid, (void *)pAppidData, sizeof(CAppidData) );
  411. if ( ! bStatus )
  412. (*pfnPrint)( "Error trying to read CAppidData at 0x%x\n", pClsidData->_pAppid );
  413. }
  414. if ( ! pAppidData )
  415. {
  416. (*pfnPrint)( "\n" );
  417. return;
  418. }
  419. (*pfnPrint)( " _wszAppid %S\n", pAppidData->_wszAppid );
  420. (*pfnPrint)( " _bActivateAtStorage %s\n", pAppidData->_bActivateAtStorage ? "TRUE" : "FALSE" );
  421. (*pfnPrint)( " _pwszService 0x%x", pAppidData->_pwszService );
  422. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pAppidData->_pwszService, (void *)String, sizeof(String) );
  423. if ( bStatus )
  424. pfnPrint( " %S", String );
  425. (*pfnPrint)( "\n" );
  426. (*pfnPrint)( " _pwszServiceParameters 0x%x", pAppidData->_pwszServiceParameters );
  427. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pAppidData->_pwszServiceParameters, (void *)String, sizeof(String) );
  428. if ( bStatus )
  429. pfnPrint( " %S", String );
  430. (*pfnPrint)( "\n" );
  431. (*pfnPrint)( " _pwszRunAsUser 0x%x", pAppidData->_pwszRunAsUser );
  432. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pAppidData->_pwszRunAsUser, (void *)String, sizeof(String) );
  433. if ( bStatus )
  434. pfnPrint( " %S", String );
  435. (*pfnPrint)( "\n" );
  436. (*pfnPrint)( " _pwszRunAsDomain 0x%x", pAppidData->_pwszRunAsDomain );
  437. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pAppidData->_pwszRunAsDomain, (void *)String, sizeof(String) );
  438. if ( bStatus )
  439. pfnPrint( " %S", String );
  440. (*pfnPrint)( "\n" );
  441. (*pfnPrint)( " _pwszRemoteServerNames 0x%x", pAppidData->_pwszRemoteServerNames );
  442. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pAppidData->_pwszRemoteServerNames, (void *)String, sizeof(String) );
  443. if ( bStatus )
  444. pfnPrint( " %S", String );
  445. (*pfnPrint)( "\n" );
  446. (*pfnPrint)( " _pLaunchPermission 0x%x (use .sd to display)\n", pAppidData->_pLaunchPermission );
  447. (*pfnPrint)( "\n" );
  448. Free( pAppidData );
  449. }
  450. void
  451. DumpSurrogates(
  452. PNTSD_EXTENSION_APIS pExtApis,
  453. HANDLE hProcess
  454. )
  455. {
  456. PNTSD_OUTPUT_ROUTINE pfnPrint;
  457. CSurrogateList * pSurrogateList = NULL;
  458. CSurrogateListEntry * pEntry = NULL;
  459. WCHAR String[256];
  460. DWORD_PTR Address;
  461. GUID Guid;
  462. BOOL bStatus;
  463. pfnPrint = pExtApis->lpOutputRoutine;
  464. // Gives us the address of gpSurrogateList.
  465. Address = (*pExtApis->lpGetExpressionRoutine)( "rpcss!gpSurrogateList" );
  466. if ( ! Address )
  467. return;
  468. pSurrogateList = (CSurrogateList *) Alloc( sizeof(CSurrogateList) );
  469. bStatus = ReadMemory( pExtApis, hProcess, Address, (void *)&Address, sizeof(DWORD) );
  470. if ( bStatus )
  471. bStatus = ReadMemory( pExtApis, hProcess, Address, (void *)pSurrogateList, sizeof(CSurrogateList) );
  472. if ( ! bStatus )
  473. return;
  474. (*pfnPrint)( " gpSurrogateList at 0x%x\n\n", Address );
  475. for(pEntry = (CSurrogateListEntry *) pSurrogateList->First();
  476. pEntry;)
  477. {
  478. (*pfnPrint)( " CSurrogateListEntry at 0x%x\n\n", pEntry );
  479. (*pfnPrint)( " SurrogateListEntry at 0x%x\n\n", pEntry );
  480. (*pfnPrint)( " _pServerListEntry 0x%x\n", pEntry->_pServerListEntry );
  481. bStatus = DumpServerListEntry( pExtApis, hProcess, (DWORD_PTR)pEntry->_pServerListEntry);
  482. if(!bStatus)
  483. break;
  484. // Read the next list element
  485. Address = (DWORD_PTR)pEntry;
  486. pEntry = (CSurrogateListEntry *) Alloc( sizeof(CSurrogateListEntry) );
  487. bStatus = ReadMemory( pExtApis, hProcess, Address, (void *)pEntry, sizeof(CSurrogateListEntry) );
  488. if(!bStatus)
  489. break;
  490. pEntry = (CSurrogateListEntry *) pEntry->Next();
  491. }
  492. }
  493. void
  494. DumpServers(
  495. PNTSD_EXTENSION_APIS pExtApis,
  496. HANDLE hProcess,
  497. CHAR * pszServerTable
  498. )
  499. {
  500. PNTSD_OUTPUT_ROUTINE pfnPrint;
  501. CServerTable * pServerTable = NULL;
  502. CServerTableEntry * pServerTableEntry = NULL;
  503. CServerListEntry * pServerListEntry = NULL;
  504. CHAR String[256];
  505. DWORD_PTR Address;
  506. GUID Guid;
  507. BOOL bStatus;
  508. pfnPrint = pExtApis->lpOutputRoutine;
  509. lstrcpy(String, "rpcss!");
  510. lstrcat(String,pszServerTable);
  511. // Gives us the address of gpProcessTable or gpClassTable.
  512. Address = (*pExtApis->lpGetExpressionRoutine)( String );
  513. if ( ! Address )
  514. {
  515. (*pfnPrint)("Could not get address for %s\n", pszServerTable);
  516. return;
  517. }
  518. pServerTable = (CServerTable *) Alloc( sizeof(CServerTable) );
  519. // Get address of the actual table
  520. bStatus = ReadMemory( pExtApis, hProcess, Address, (void *)&Address, sizeof(DWORD) );
  521. if ( bStatus )
  522. bStatus = ReadMemory( pExtApis, hProcess, Address, (void *)pServerTable, sizeof(CServerTable) );
  523. if ( ! bStatus )
  524. return;
  525. (*pfnPrint)( " %s at 0x%x\n\n", pszServerTable, Address );
  526. (*pfnPrint)( " CHashTable::_cBuckets %d\n", pServerTable->_cBuckets );
  527. (*pfnPrint)( " CHashTable::_cElements %d\n\n", pServerTable->_cElements );
  528. if ( 0 == pServerTable->_cElements ) // nothing to show, table is empty
  529. return;
  530. Address = (DWORD_PTR) pServerTable->_buckets;
  531. pServerTable->_buckets = (CTableElement **) Alloc( pServerTable->_cBuckets * sizeof(CTableElement *) );
  532. bStatus = ReadMemory(
  533. pExtApis,
  534. hProcess,
  535. Address,
  536. (void *)pServerTable->_buckets,
  537. pServerTable->_cBuckets * sizeof(CTableElement *) );
  538. if ( ! bStatus )
  539. return;
  540. for ( DWORD n = 0; n < pServerTable->_cBuckets; n++ )
  541. {
  542. for ( DWORD_PTR ClassAddress = (DWORD_PTR) pServerTable->_buckets[n];
  543. ClassAddress;
  544. ClassAddress = (DWORD_PTR) pServerTableEntry->_pnext )
  545. {
  546. pServerTableEntry = (CServerTableEntry *) Alloc( sizeof(CServerTableEntry) );
  547. bStatus = ReadMemory(
  548. pExtApis,
  549. hProcess,
  550. ClassAddress,
  551. (void *)pServerTableEntry,
  552. sizeof(CServerTableEntry) );
  553. (*pfnPrint)( " CServerTableEntry 0x%x ", ClassAddress );
  554. if ( ! bStatus )
  555. {
  556. (*pfnPrint)( "[couldn't read address]\n" );
  557. break;
  558. }
  559. ((ID UNALIGNED *)&Guid)[0] = pServerTableEntry->_id;
  560. ((ID UNALIGNED *)&Guid)[1] = pServerTableEntry->_id2;
  561. DumpGuid( pExtApis, Guid );
  562. (*pfnPrint)( "\n _references %d", pServerTableEntry->_references );
  563. (*pfnPrint)( "\n _EntryType ");
  564. switch(pServerTableEntry->_EntryType)
  565. {
  566. case ENTRY_TYPE_CLASS: (*pfnPrint)("ENTRY_TYPE_CLASS"); break;
  567. case ENTRY_TYPE_PROCESS: (*pfnPrint)("ENTRY_TYPE_PROCESS"); break;
  568. default:
  569. (*pfnPrint)(" !ERROR! Unknown server entry type!");
  570. break;
  571. }
  572. (*pfnPrint)( "\n _pParentTableLock 0x%x", pServerTableEntry->_pParentTableLock );
  573. (*pfnPrint)( "\n _pParentTable 0x%x", pServerTableEntry->_pParentTable );
  574. (*pfnPrint)( "\n _dwProcessId 0x%x (%d)", pServerTableEntry->_dwProcessId, pServerTableEntry->_dwProcessId );
  575. (*pfnPrint)( "\n _pProcess 0x%x", pServerTableEntry->_pProcess );
  576. (*pfnPrint)( "\n _pvRunAsHandle 0x%x", pServerTableEntry->_pvRunAsHandle );
  577. (*pfnPrint)( "\n _bSuspendedClsid 0x%x", pServerTableEntry->_bSuspendedClsid );
  578. (*pfnPrint)( "\n _bSuspendedApplication 0x%x", pServerTableEntry->_bSuspendedApplication );
  579. (*pfnPrint)( "\n");
  580. (*pfnPrint)( " _ServerList :\n" );
  581. // Allocate enough space to hold a single CServerListEntry
  582. pServerListEntry = (CServerListEntry*) alloca(sizeof(CServerListEntry));
  583. if (!pServerListEntry)
  584. return;
  585. DWORD_PTR ServerAddress = 0;
  586. ServerAddress = (DWORD_PTR) (CServerListEntry *)pServerTableEntry->_ServerList._first;
  587. while (ServerAddress)
  588. {
  589. bStatus = DumpServerListEntry(pExtApis, hProcess, ServerAddress);
  590. if(!bStatus)
  591. break;
  592. // Walk to the next list element:
  593. bStatus = ReadMemory(
  594. pExtApis,
  595. hProcess,
  596. ServerAddress,
  597. (void*)pServerListEntry,
  598. sizeof(CServerListEntry));
  599. if (!bStatus)
  600. break;
  601. ServerAddress = (DWORD_PTR)(CServerListEntry*)pServerListEntry->_flink;
  602. }
  603. (*pfnPrint)( "\n" );
  604. } // for class table entries in bucket
  605. } // for class table buckets
  606. }
  607. DWORD
  608. DumpServerListEntry(
  609. PNTSD_EXTENSION_APIS pExtApis,
  610. HANDLE hProcess,
  611. DWORD_PTR ServerAddress
  612. )
  613. {
  614. PNTSD_OUTPUT_ROUTINE pfnPrint;
  615. CServerListEntry * pServerListEntry = NULL;
  616. BOOL bStatus;
  617. pfnPrint = pExtApis->lpOutputRoutine;
  618. pServerListEntry = (CServerListEntry *) Alloc( sizeof(CServerListEntry) );
  619. bStatus = ReadMemory(
  620. pExtApis,
  621. hProcess,
  622. ServerAddress,
  623. (void *)pServerListEntry,
  624. sizeof(CServerListEntry) );
  625. (*pfnPrint)( " CServerListEntry 0x%x ", ServerAddress );
  626. if ( ! bStatus )
  627. {
  628. (*pfnPrint)( "[couldn't read address]\n" );
  629. return bStatus;
  630. }
  631. (*pfnPrint)( "\n" );
  632. (*pfnPrint)( "\t_references %d\n", pServerListEntry->_references );
  633. (*pfnPrint)( "\t_pServerTableEntry 0x%x\n", pServerListEntry->_pServerTableEntry );
  634. (*pfnPrint)( "\t_pServerProcess 0x%x\n", pServerListEntry->_pServerProcess );
  635. (*pfnPrint)( "\t_hRpc 0x%x\n", pServerListEntry->_hRpc );
  636. (*pfnPrint)( "\t_hRpcAnonymous 0x%x\n", pServerListEntry->_hRpcAnonymous );
  637. (*pfnPrint)( "\t_ipid 0x%x\n", pServerListEntry->_ipid );
  638. (*pfnPrint)( "\t_Context %d ", pServerListEntry->_Context );
  639. switch ( pServerListEntry->_Context )
  640. {
  641. case SERVER_ACTIVATOR :
  642. (*pfnPrint)( "Activator\n" );
  643. break;
  644. case SERVER_SERVICE :
  645. (*pfnPrint)( "Service\n" );
  646. break;
  647. case SERVER_RUNAS :
  648. (*pfnPrint)( "RunAs\n" );
  649. break;
  650. default :
  651. (*pfnPrint)( "\n" );
  652. }
  653. (*pfnPrint)( "\t_State 0x%x ", pServerListEntry->_State );
  654. if ( pServerListEntry->_State & SERVERSTATE_SUSPENDED )
  655. (*pfnPrint)( "Suspended " );
  656. else
  657. (*pfnPrint)( "Running " );
  658. if ( pServerListEntry->_State & SERVERSTATE_SINGLEUSE )
  659. (*pfnPrint)( "SingleUse " );
  660. if ( pServerListEntry->_State & SERVERSTATE_SURROGATE )
  661. (*pfnPrint)( "Surrogate " );
  662. (*pfnPrint)( "\n" );
  663. (*pfnPrint)( "\t_NumCalls %d\n", pServerListEntry->_NumCalls );
  664. (*pfnPrint)( "\t_RegistrationKey 0x%x\n", pServerListEntry->_RegistrationKey );
  665. (*pfnPrint)( "\t_lThreadToken 0x%x\n", pServerListEntry->_lThreadToken );
  666. return bStatus;
  667. }
  668. void
  669. DumpProcess(
  670. PNTSD_EXTENSION_APIS pExtApis,
  671. HANDLE hProcess,
  672. CProcess * pProcess,
  673. char* pszProcessAddr
  674. )
  675. {
  676. PNTSD_OUTPUT_ROUTINE pfnPrint;
  677. CToken * pToken;
  678. CClassReg * pClassReg = NULL;
  679. WCHAR String[256];
  680. DWORD TokenSize;
  681. DWORD_PTR ClassRegAddr;
  682. BOOL bStatus;
  683. DWORD i;
  684. DWORD dwProcessAddr;
  685. pfnPrint = pExtApis->lpOutputRoutine;
  686. dwProcessAddr = strtol(pszProcessAddr, NULL, 16);
  687. (*pfnPrint)( " _cClientReferences %d\n", pProcess->_cClientReferences );
  688. pToken = 0;
  689. if ( pProcess->_pToken )
  690. {
  691. TokenSize = sizeof(CToken);
  692. pToken = (CToken *) Alloc( TokenSize );
  693. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pProcess->_pToken, (void *)pToken, TokenSize );
  694. if ( bStatus )
  695. {
  696. TokenSize += (pToken->_sid.SubAuthorityCount - 1) * sizeof(ULONG);
  697. Free( pToken );
  698. pToken = (CToken *) Alloc( TokenSize );
  699. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pProcess->_pToken, (void *)pToken, TokenSize );
  700. }
  701. }
  702. (*pfnPrint)( " _pToken 0x%x\n", pProcess->_pToken );
  703. DumpToken( pExtApis, hProcess, pToken );
  704. Free( pToken );
  705. (*pfnPrint)( " _pwszWinstaDesktop 0x%x", pProcess->_pwszWinstaDesktop );
  706. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pProcess->_pwszWinstaDesktop, (void *)String, sizeof(String) );
  707. if ( bStatus )
  708. pfnPrint( " %S", String );
  709. (*pfnPrint)( "\n" );
  710. (*pfnPrint)( " _hProcess 0x%x\n", pProcess->_hProcess);
  711. (*pfnPrint)( " _fCacheFree 0x%x\n", pProcess->_fCacheFree);
  712. (*pfnPrint)( " _pdsaLocalBindings 0x%x", pProcess->_pdsaLocalBindings);
  713. if (pProcess->_pdsaLocalBindings)
  714. {
  715. (*pfnPrint)(" (\"!rpcssext.dsa 0x%x\" to see contents)", pProcess->_pdsaLocalBindings);
  716. }
  717. (*pfnPrint)("\n");
  718. (*pfnPrint)( " _pdsaRemoteBindings 0x%x", pProcess->_pdsaRemoteBindings);
  719. if (pProcess->_pdsaRemoteBindings)
  720. {
  721. (*pfnPrint)(" (run \"!rpcssext.dsa 0x%x\" to see contents)", pProcess->_pdsaRemoteBindings);
  722. }
  723. (*pfnPrint)("\n");
  724. // Dump list of oxids
  725. (*pfnPrint)(" _blistOxids (_ulcElements=0x%x, _ulmaxData=0x%x) (\"!rpcssext.blsoxids 0x%x\" to dump list contents)\n",
  726. pProcess->_blistOxids._ulcElements,
  727. pProcess->_blistOxids._ulmaxData,
  728. dwProcessAddr + offsetof(CProcess, _blistOxids) );
  729. // UNDONE _blistOids
  730. //CClientOid** ppoids = (CClientOid**)alloca(pProcess->_blist
  731. (*pfnPrint)( " _pScmProcessReg 0x%x\n", pProcess->_pScmProcessReg);
  732. if (pProcess->_pScmProcessReg)
  733. {
  734. ScmProcessReg spr;
  735. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pProcess->_pScmProcessReg, (void*)&spr, sizeof(ScmProcessReg));
  736. if (bStatus)
  737. {
  738. (*pfnPrint)( " _pScmProcessReg->ProcessGuid ");
  739. DumpGuid(pExtApis, spr.ProcessGUID);
  740. (*pfnPrint)( "\n");
  741. (*pfnPrint)( " _pScmProcessReg->RegistrationToken 0x%x\n", spr.RegistrationToken);
  742. (*pfnPrint)( " _pScmProcessReg->ReadinessStatus 0x%x\n", spr.ReadinessStatus);
  743. (*pfnPrint)( " _pScmProcessReg->TimeOfLastPing._Time 0x%x\n", spr.TimeOfLastPing._Time);
  744. }
  745. }
  746. (*pfnPrint)( " _fLockValid 0x%x\n", pProcess->_fLockValid);
  747. (*pfnPrint)( " _fReadCustomProtseqs 0x%x\n", pProcess->_fReadCustomProtseqs);
  748. (*pfnPrint)( " _pdsaCustomProtseqs 0x%x", pProcess->_pdsaCustomProtseqs);
  749. if (pProcess->_pdsaCustomProtseqs)
  750. {
  751. (*pfnPrint)(" (run \"!rpcssext.dsa 0x%x\" to see contents)", pProcess->_pdsaCustomProtseqs);
  752. }
  753. (*pfnPrint)("\n");
  754. (*pfnPrint)( " _pvRunAsHandle 0x%x\n", pProcess->_pvRunAsHandle);
  755. (*pfnPrint)( " _listClasses\n" );
  756. ClassRegAddr = (DWORD_PTR) pProcess->_listClasses._first;
  757. if ( ! ClassRegAddr )
  758. (*pfnPrint)( " (empty)\n" );
  759. while ( ClassRegAddr )
  760. {
  761. pClassReg = (CClassReg *) Alloc( sizeof( CClassReg ) );
  762. if (pClassReg)
  763. {
  764. bStatus = ReadMemory( pExtApis, hProcess, ClassRegAddr, (void *)pClassReg, sizeof( CClassReg ) );
  765. (*pfnPrint)( " _Guid = " );
  766. DumpGuid( pExtApis, pClassReg->_Guid );
  767. (*pfnPrint)( " _Reg = %d\n", pClassReg->_Reg );
  768. ClassRegAddr = (DWORD_PTR) pClassReg->_flink;
  769. }
  770. }
  771. (*pfnPrint)( " _procID = %d\n", pProcess->_procID );
  772. (*pfnPrint)( " _hProcHandle = 0x%x\n", pProcess->_hProcHandle );
  773. (*pfnPrint)( " _dwFlags = 0x%x (", pProcess->_dwFlags);
  774. if (pProcess->_dwFlags & PROCESS_SUSPENDED)
  775. (*pfnPrint)(" PROCESS_SUSPENDED");
  776. if (pProcess->_dwFlags & PROCESS_RETIRED)
  777. (*pfnPrint)(" PROCESS_RETIRED");
  778. if (pProcess->_dwFlags & PROCESS_SPI_DIRTY)
  779. (*pfnPrint)(" PROCESS_SPI_DIRTY");
  780. if (pProcess->_dwFlags & PROCESS_RUNDOWN)
  781. (*pfnPrint)(" PROCESS_RUNDOWN");
  782. if (pProcess->_dwFlags & PROCESS_PAUSED)
  783. (*pfnPrint)(" PROCESS_PAUSED");
  784. (*pfnPrint)(" )\n");
  785. (*pfnPrint)( " _ftCreated = 0x%I64x", pProcess->_ftCreated );
  786. SYSTEMTIME systime;
  787. // The scm records the current UTC time when a process starts up; we convert it here
  788. // to local time for easier readibility.
  789. FILETIME ftLocal;
  790. if (FileTimeToLocalFileTime(&(pProcess->_ftCreated), &ftLocal))
  791. {
  792. if (FileTimeToSystemTime(&ftLocal, &systime))
  793. {
  794. (*pfnPrint)( " (created at %d:%d:%d on %d/%d/%d)",
  795. systime.wHour,
  796. systime.wMinute,
  797. systime.wSecond,
  798. systime.wMonth,
  799. systime.wDay,
  800. systime.wYear);
  801. }
  802. }
  803. (*pfnPrint)( "\n" );
  804. (*pfnPrint)( "\n" );
  805. }
  806. void
  807. DumpBListOxids(
  808. PNTSD_EXTENSION_APIS pExtApis,
  809. HANDLE hProcess,
  810. CBList* plist
  811. )
  812. {
  813. PNTSD_OUTPUT_ROUTINE pfnPrint;
  814. pfnPrint = pExtApis->lpOutputRoutine;
  815. (*pfnPrint)("undone\n");
  816. }
  817. void
  818. DumpToken(
  819. PNTSD_EXTENSION_APIS pExtApis,
  820. HANDLE hProcess,
  821. CToken * pToken
  822. )
  823. {
  824. PNTSD_OUTPUT_ROUTINE pfnPrint;
  825. SID_NAME_USE SidNameUse;
  826. UNICODE_STRING UnicodeString;
  827. char UserName[32];
  828. char DomainName[32];
  829. DWORD UserNameSize;
  830. DWORD DomainNameSize;
  831. BOOL bStatus;
  832. pfnPrint = pExtApis->lpOutputRoutine;
  833. (*pfnPrint)( " _luid %d %d\n", pToken->_luid.LowPart, pToken->_luid.HighPart );
  834. UnicodeString.Length = UnicodeString.MaximumLength = 0;
  835. UnicodeString.Buffer = 0;
  836. (void) RtlConvertSidToUnicodeString(
  837. &UnicodeString,
  838. &pToken->_sid,
  839. (BOOLEAN)TRUE // Allocate
  840. );
  841. (*pfnPrint)( " _sid %S", UnicodeString.Buffer );
  842. RtlFreeUnicodeString( &UnicodeString );
  843. UserNameSize = sizeof(UserName) / sizeof(char);
  844. DomainNameSize = sizeof(DomainName) / sizeof(char);
  845. bStatus = LookupAccountSid(
  846. NULL,
  847. &pToken->_sid,
  848. UserName,
  849. &UserNameSize,
  850. DomainName,
  851. &DomainNameSize,
  852. &SidNameUse );
  853. if ( bStatus )
  854. (*pfnPrint)( " (%s\\%s)", DomainName, UserName );
  855. (*pfnPrint)( "\n" );
  856. }
  857. void
  858. DumpRemoteList(
  859. PNTSD_EXTENSION_APIS pExtApis,
  860. HANDLE hProcess
  861. )
  862. {
  863. PNTSD_OUTPUT_ROUTINE pfnPrint;
  864. CRemoteMachineList * pMachineList = NULL;
  865. CRemoteMachine * pRemoteMachine = NULL;
  866. CMachineBinding * pBindEntry;
  867. WCHAR String[256];
  868. DWORD_PTR Address;
  869. GUID Guid;
  870. BOOL bStatus;
  871. pfnPrint = pExtApis->lpOutputRoutine;
  872. // Gives us the address of gpRemoteMachineList.
  873. Address = (*pExtApis->lpGetExpressionRoutine)( "rpcss!gpRemoteMachineList" );
  874. if ( ! Address )
  875. return;
  876. pMachineList = (CRemoteMachineList *) Alloc( sizeof(CRemoteMachineList) );
  877. bStatus = ReadMemory( pExtApis, hProcess, Address, (void *)&Address, sizeof(DWORD) );
  878. if ( bStatus )
  879. bStatus = ReadMemory( pExtApis, hProcess, Address, (void *)pMachineList, sizeof(CRemoteMachineList) );
  880. if ( ! bStatus )
  881. return;
  882. (*pfnPrint)( " gpRemoteMachineList at 0x%x\n", Address );
  883. for ( DWORD_PTR MachineAddress = (DWORD_PTR) (CRemoteMachine *)pMachineList->_first;
  884. MachineAddress;
  885. MachineAddress = (DWORD_PTR) (CRemoteMachine *)pRemoteMachine->_flink )
  886. {
  887. pRemoteMachine = (CRemoteMachine *) Alloc( sizeof(CRemoteMachine) );
  888. bStatus = ReadMemory(
  889. pExtApis,
  890. hProcess,
  891. MachineAddress,
  892. (void *)pRemoteMachine,
  893. sizeof(CRemoteMachine) );
  894. (*pfnPrint)( "\n CRemoteMachine 0x%x ", MachineAddress );
  895. if ( ! bStatus )
  896. {
  897. (*pfnPrint)( "[couldn't read address]\n" );
  898. break;
  899. }
  900. bStatus = ReadMemory( pExtApis, hProcess, (DWORD_PTR)pRemoteMachine->_pwszMachine, (void *)String, sizeof(String) );
  901. if ( bStatus )
  902. pfnPrint( "%S", String );
  903. (*pfnPrint)( "\n" );
  904. for ( DWORD_PTR BindAddress = (DWORD_PTR) (CMachineBinding *)pRemoteMachine->_BindingList._first;
  905. BindAddress;
  906. BindAddress = (DWORD_PTR) (CMachineBinding *)pBindEntry->_flink )
  907. {
  908. pBindEntry = (CMachineBinding *) Alloc( sizeof(CMachineBinding) );
  909. bStatus = ReadMemory(
  910. pExtApis,
  911. hProcess,
  912. BindAddress,
  913. (void *)pBindEntry,
  914. sizeof(CMachineBinding) );
  915. (*pfnPrint)( " CMachineBinding 0x%x ", BindAddress );
  916. if ( ! bStatus )
  917. {
  918. (*pfnPrint)( "[couldn't read address]\n" );
  919. break;
  920. }
  921. (*pfnPrint)( "\n" );
  922. (*pfnPrint)( " _hBinding 0x%x\n", pBindEntry->_hBinding );
  923. (*pfnPrint)( " _ProtseqId 0x%x %S\n", pBindEntry->_ProtseqId, gaProtseqInfo[pBindEntry->_ProtseqId].pwstrProtseq );
  924. (*pfnPrint)( " _AuthnSvc 0x%x\n", pBindEntry->_AuthnSvc);
  925. (*pfnPrint)( " _pAuthInfo 0x%x\n", pBindEntry->_pAuthInfo );
  926. }
  927. }
  928. }
  929. void
  930. DumpSPI(
  931. PNTSD_EXTENSION_APIS pExtApis,
  932. HANDLE hProcess,
  933. SCMProcessInfo* pSPI
  934. )
  935. {
  936. }