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.

2676 lines
80 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. sceExts.cxx
  5. Abstract:
  6. This function contains the SCE ntsd debugger extensions
  7. Each DLL entry point is called with a handle to the process being
  8. debugged, as well as pointers to functions.
  9. This process cannot just _read data in the process being debugged.
  10. Therefore, some macros are defined that will copy data from
  11. the debuggee process into a location in this processes memory.
  12. The GET_DATA and GET_STRING macros (defined in this file) are used
  13. to _read memory in the process being debugged. The DebuggeeAddr is the
  14. address of the memory in the debuggee process. The LocalAddr is the
  15. address of memory in the debugger (this programs context) that data is
  16. to be copied into. Length describes the number of bytes to be copied.
  17. Author:
  18. Jin Huang (JinHuang) 3-Apr-2001
  19. Revision History:
  20. --*/
  21. #include "sceexts.h"
  22. //
  23. // globals
  24. //
  25. HANDLE GlobalhCurrentProcess;
  26. BOOL Status;
  27. //=======================
  28. // Function Prototypes
  29. //=======================
  30. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  31. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  32. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  33. //
  34. // Initialize the global function pointers
  35. //
  36. VOID
  37. InitFunctionPointers(
  38. HANDLE hCurrentProcess,
  39. PNTSD_EXTENSION_APIS lpExtensionApis
  40. )
  41. {
  42. //
  43. // Load these to speed access if we haven't already
  44. //
  45. if (!lpOutputRoutine) {
  46. lpOutputRoutine = lpExtensionApis->lpOutputRoutine;
  47. lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine;
  48. lpCheckControlCRoutine = lpExtensionApis->lpCheckControlCRoutine;
  49. }
  50. //
  51. // Stick this in a global
  52. //
  53. GlobalhCurrentProcess = hCurrentProcess;
  54. }
  55. VOID
  56. help(
  57. HANDLE hCurrentProcess,
  58. HANDLE hCurrentThread,
  59. DWORD dwCurrentPc,
  60. PNTSD_EXTENSION_APIS lpExtensionApis,
  61. LPSTR lpArgumentString
  62. )
  63. /*++
  64. Routine Description:
  65. Provides online help for the user of this debugger extension.
  66. Arguments:
  67. hCurrentProcess - Handle for the process being debugged.
  68. hCurrentThread - Handle for the thread that has the debugger focus.
  69. dwCurrentPc - Current Program Counter?
  70. lpExtensionApis - Pointer to a structure that contains pointers to
  71. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  72. typedef struct _NTSD_EXTENSION_APIS {
  73. DWORD nSize;
  74. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  75. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  76. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  77. PNTSD_DISASM lpDisasmRoutine;
  78. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  79. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  80. lpArgumentString - This is a pointer to a string that contains
  81. space seperated arguments that are passed to debugger
  82. extension function.
  83. Return Value:
  84. --*/
  85. {
  86. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  87. DebuggerOut("\nSecurity Configuration Engine NTSD Extensions\n");
  88. if (!lpArgumentString || *lpArgumentString == '\0' ||
  89. *lpArgumentString == '\n' || *lpArgumentString == '\r')
  90. {
  91. DebuggerOut("\tDumpScePrivileges - dump SCE predefined privileges\n");
  92. DebuggerOut("\tDumpSceWellKnownNames - dump SCE well known names\n");
  93. DebuggerOut("\tDumpSceSplayTree - dump splay tree structure\n");
  94. DebuggerOut("\tDumpScePolicyQueue - dump policy queue status & nodes\n");
  95. DebuggerOut("\tDumpSceServerState - dump SCE server states\n");
  96. DebuggerOut("\tDumpScePolicyNotification - dump policy change notifications in client\n");
  97. DebuggerOut("\tDumpSceSetupDcpromoState - dump SCE setup/dcpromo status\n");
  98. DebuggerOut("\tDumpScePolicyPropStatus - dump policy propagation status\n");
  99. DebuggerOut("\tDumpSceNameList - dump SCE_NAME_LIST list\n");
  100. DebuggerOut("\tDumpSceNameStatusList - dump SCE_NAME_STATUS_LIST list\n");
  101. DebuggerOut("\tDumpSceADLTable - dump SCEP_ADL_NODE table (for SD comparison)\n");
  102. DebuggerOut("\tDumpSceADLNodes - dump SCEP_ADL_NODE nodes in one bucket\n");
  103. DebuggerOut("\tDumpSceObjectTree - dump SCEP_OBJECT_TREE tree\n");
  104. DebuggerOut("\tDumpScePrivilegeValueList - dump SCE_PRIVILEGE_VALUE_LIST\n");
  105. DebuggerOut("\tDumpSceErrorLogInfo - dump SCE_ERROR_LOG_INFO\n");
  106. DebuggerOut("\tDumpScePrivilegeAssignment - dump SCE_PRIVILEGE_ASSIGNMENT\n");
  107. DebuggerOut("\tDumpSceServices - dump SCE_SERVICES\n");
  108. DebuggerOut("\tDumpSceGroupMembership - dump SCE_GROUP_MEMBERSHIP\n");
  109. DebuggerOut("\tDumpSceObjectSecurity - dump SCE_OBJECT_SECURITY\n");
  110. DebuggerOut("\tDumpSceObjectList - dump SCE_OBJECT_LIST\n");
  111. DebuggerOut("\tDumpSceObjectArray - dump SCE_OBJECT_ARRAY\n");
  112. DebuggerOut("\tDumpSceRegistryValues - dump SCE_REGISTRY_VALUE_INFO nodes\n");
  113. DebuggerOut("\n\tEnter help <cmd> for detailed help on a command\n");
  114. }
  115. else if (!_stricmp(lpArgumentString, "DumpScePrivileges")) {
  116. DebuggerOut("\tlpArgumentString <arg>, where <arg> can be one of:\n", lpArgumentString);
  117. DebuggerOut("\t\tno argument - dump all SCE predefined privileges\n");
  118. DebuggerOut("\t\tindex <index> - dump the privilege at specified index\n");
  119. }
  120. else if (!_stricmp(lpArgumentString, "DumpScePolicyQueue")) {
  121. DebuggerOut("\t%s <arg>, where <arg> can be one of:\n", lpArgumentString);
  122. DebuggerOut("\t\tno argument - dump all policy queue status & nodes\n");
  123. DebuggerOut("\t\t<address> - dump the policy queue node from this address\n");
  124. }
  125. else if (!_stricmp(lpArgumentString, "DumpSceWellKnownNames") ||
  126. !_stricmp(lpArgumentString, "DumpSceServerState") ||
  127. !_stricmp(lpArgumentString, "DumpScePolicyNotification") ||
  128. !_stricmp(lpArgumentString, "DumpSceSetupDcpromoState") ||
  129. !_stricmp(lpArgumentString, "DumpScePolicyPropStatus") ) {
  130. DebuggerOut("\t%s <no argument>\n", lpArgumentString);
  131. }
  132. else if (!_stricmp(lpArgumentString, "DumpSceSplayTree") ||
  133. !_stricmp(lpArgumentString, "DumpSceNameList") ||
  134. !_stricmp(lpArgumentString, "DumpSceNameStatusList") ||
  135. !_stricmp(lpArgumentString, "DumpSceADLTable") ||
  136. !_stricmp(lpArgumentString, "DumpSceADLNodes") ||
  137. !_stricmp(lpArgumentString, "DumpScePrivilegeValueList") ||
  138. !_stricmp(lpArgumentString, "DumpSceErrorLogInfo") ||
  139. !_stricmp(lpArgumentString, "DumpScePrivilegeAssignment") ||
  140. !_stricmp(lpArgumentString, "DumpSceServices") ||
  141. !_stricmp(lpArgumentString, "DumpSceGroupMembership") ||
  142. !_stricmp(lpArgumentString, "DumpSceObjectSecurity") ||
  143. !_stricmp(lpArgumentString, "DumpSceObjectList") ) {
  144. DebuggerOut("\t%s <address>\n", lpArgumentString);
  145. }
  146. else if (!_stricmp(lpArgumentString, "DumpSceRegistryValues") ) {
  147. DebuggerOut("\t%s <arg>, where <arg> can be:\n", lpArgumentString);
  148. DebuggerOut("\t\t<address> - Dump one node\n");
  149. DebuggerOut("\t\t-s <si> -e <ei> <address> - Dump multiple nodes specified by start index <si> and end index <ei>\n");
  150. }
  151. else if (!_stricmp(lpArgumentString, "DumpSceObjectArray") ) {
  152. DebuggerOut("\t%s <arg>, where <arg> can be:\n", lpArgumentString);
  153. DebuggerOut("\t\t<address> - Dump all nodes in the array\n");
  154. DebuggerOut("\t\t-s <si> -c <Count> <address> - Dump multiple nodes specified by start index <si> and <Count>\n");
  155. }
  156. else if (!_stricmp(lpArgumentString, "DumpSceObjectTree") ) {
  157. DebuggerOut("\t%s <arg>, where <arg> can be:\n", lpArgumentString);
  158. DebuggerOut("\t\t[-s] <address> - Dump the tree in one level, with option to dump SD\n");
  159. DebuggerOut("\t\t-r <Level> [-s] <address> - Dump the tree in levels specified by <Level>, with option to dump SD\n");
  160. DebuggerOut("\t\t-m <Max> -n <Name> [-s] <address> - Dump the tree in one level, start at <Name> for <Max> nodes.\n");
  161. }
  162. else {
  163. DebuggerOut("\tInvalid command [%s]\n", lpArgumentString);
  164. }
  165. }
  166. VOID
  167. DumpScePrivileges(
  168. HANDLE hCurrentProcess,
  169. HANDLE hCurrentThread,
  170. DWORD dwCurrentPc,
  171. PNTSD_EXTENSION_APIS lpExtensionApis,
  172. LPSTR lpArgumentString
  173. )
  174. /*++
  175. Routine Description:
  176. Dump SCE_Privileges contents
  177. Arguments:
  178. hCurrentProcess - Handle for the process being debugged.
  179. hCurrentThread - Handle for the thread that has the debugger focus.
  180. dwCurrentPc - Current Program Counter?
  181. lpExtensionApis - Pointer to a structure that contains pointers to
  182. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  183. typedef struct _NTSD_EXTENSION_APIS {
  184. DWORD nSize;
  185. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  186. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  187. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  188. PNTSD_DISASM lpDisasmRoutine;
  189. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  190. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  191. lpArgumentString - This is a pointer to a string that contains
  192. space seperated arguments that are passed to debugger
  193. extension function.
  194. Return Value:
  195. none
  196. --*/
  197. {
  198. PVOID pvAddr;
  199. int index=0;
  200. BOOL bAll=FALSE;
  201. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  202. //
  203. // get arguments
  204. //
  205. if (lpArgumentString && *lpArgumentString != '\0' )
  206. {
  207. DebuggerOut("Processing '%s'\n", lpArgumentString);
  208. if ( _strnicmp(lpArgumentString,"index ", 6) == 0 ) {
  209. index = atoi(lpArgumentString+6);
  210. } else {
  211. bAll = TRUE;
  212. }
  213. } else {
  214. bAll = TRUE;
  215. }
  216. //
  217. // Get the address of SCE_Privileges.
  218. //
  219. pvAddr = (PVOID)(lpGetExpressionRoutine)(SCEEXTS_PRIVILEGE_LIST);
  220. DebuggerOut("Privilege List (@%p) \n", pvAddr);
  221. if ( pvAddr ) {
  222. DWORD Value=0;
  223. WCHAR Name[MAX_PATH];
  224. PWSTR pStr=NULL;
  225. PBYTE pIndexAddr = NULL;
  226. if ( !bAll ) {
  227. if ( index >= 0 && index < cPrivCnt ) {
  228. Name[0] = L'\0';
  229. pIndexAddr = (PBYTE)pvAddr+index*(sizeof(DWORD)+sizeof(PWSTR));
  230. GET_DATA( (LPVOID)pIndexAddr, (LPVOID)&Value, sizeof(DWORD));
  231. GET_DATA( (LPVOID)(pIndexAddr+sizeof(DWORD)), (LPVOID)&pStr, sizeof(PWSTR));
  232. if ( pStr) {
  233. GET_STRING( pStr, Name, MAX_PATH);
  234. }
  235. DebuggerOut("\tValue: %d\tName: %ws\n", Value, Name);
  236. } else {
  237. DebuggerOut("\tInvalid index %d\n", index);
  238. }
  239. } else {
  240. for (index=0; index<cPrivCnt; index++) {
  241. Name[0] = L'\0';
  242. pIndexAddr = (PBYTE)pvAddr+index*(sizeof(DWORD)+sizeof(PWSTR));
  243. GET_DATA( (LPVOID)pIndexAddr, (LPVOID)&Value, sizeof(DWORD));
  244. GET_DATA( (LPVOID)(pIndexAddr+sizeof(DWORD)), (LPVOID)&pStr, sizeof(PWSTR));
  245. if ( pStr) {
  246. GET_STRING( pStr, Name, MAX_PATH);
  247. }
  248. DebuggerOut("\tIndex: %d\tValue: %d\tName: %ws\n", index, Value, Name);
  249. }
  250. }
  251. } else {
  252. DebuggerOut("\tCan't get privilege list address\n");
  253. }
  254. }
  255. VOID
  256. DumpSceWellKnownNames(
  257. HANDLE hCurrentProcess,
  258. HANDLE hCurrentThread,
  259. DWORD dwCurrentPc,
  260. PNTSD_EXTENSION_APIS lpExtensionApis,
  261. LPSTR lpArgumentString
  262. )
  263. /*++
  264. Routine Description:
  265. Dump NameTable contents.
  266. Arguments:
  267. hCurrentProcess - Handle for the process being debugged.
  268. hCurrentThread - Handle for the thread that has the debugger focus.
  269. dwCurrentPc - Current Program Counter?
  270. lpExtensionApis - Pointer to a structure that contains pointers to
  271. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  272. typedef struct _NTSD_EXTENSION_APIS {
  273. DWORD nSize;
  274. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  275. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  276. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  277. PNTSD_DISASM lpDisasmRoutine;
  278. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  279. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  280. lpArgumentString - This is a pointer to a string that contains
  281. space seperated arguments that are passed to debugger
  282. extension function.
  283. Return Value:
  284. none
  285. --*/
  286. {
  287. PVOID pvAddr;
  288. int index=0;
  289. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  290. //
  291. // Get the address of NameTable
  292. //
  293. pvAddr = (PVOID)(lpGetExpressionRoutine)(SCEEXTS_WELLKNOWN_NAMES);
  294. DebuggerOut("Wellknown Names (@%p) \n", pvAddr);
  295. if ( pvAddr ) {
  296. DWORD Value=0;
  297. WCHAR Sid[MAX_PATH];
  298. WCHAR Name[MAX_PATH];
  299. PWSTR pStrSid=NULL;
  300. PBYTE pIndexAddr = NULL;
  301. for (index=0; index<NAME_TABLE_SIZE; index++) {
  302. Name[0] = L'\0';
  303. Sid[0] = L'\0';
  304. pIndexAddr = (PBYTE)pvAddr+index*sizeof(WELL_KNOWN_NAME_LOOKUP);
  305. GET_DATA( (LPVOID)pIndexAddr, (LPVOID)&pStrSid, sizeof(PWSTR));
  306. if ( pStrSid) {
  307. GET_STRING( pStrSid, Sid, MAX_PATH);
  308. }
  309. GET_STRING( (LPWSTR)(pIndexAddr+sizeof(PWSTR)), Name, MAX_PATH);
  310. DebuggerOut("\tSid: %ws\tName: %ws\n", Sid, Name);
  311. }
  312. } else {
  313. DebuggerOut("\tCan't get well known name table address\n");
  314. }
  315. }
  316. VOID
  317. DumpSceSplayTree(
  318. HANDLE hCurrentProcess,
  319. HANDLE hCurrentThread,
  320. DWORD dwCurrentPc,
  321. PNTSD_EXTENSION_APIS lpExtensionApis,
  322. LPSTR lpArgumentString
  323. )
  324. /*++
  325. Routine Description:
  326. Dump splay structure.
  327. Arguments:
  328. hCurrentProcess - Handle for the process being debugged.
  329. hCurrentThread - Handle for the thread that has the debugger focus.
  330. dwCurrentPc - Current Program Counter?
  331. lpExtensionApis - Pointer to a structure that contains pointers to
  332. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  333. typedef struct _NTSD_EXTENSION_APIS {
  334. DWORD nSize;
  335. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  336. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  337. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  338. PNTSD_DISASM lpDisasmRoutine;
  339. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  340. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  341. lpArgumentString - This is a pointer to a string that contains
  342. space seperated arguments that are passed to debugger
  343. extension function.
  344. Return Value:
  345. none
  346. --*/
  347. {
  348. PVOID pvAddr;
  349. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  350. //
  351. // get address of the tree
  352. //
  353. if (lpArgumentString && *lpArgumentString != '\0' )
  354. {
  355. pvAddr = (PVOID)(lpGetExpressionRoutine)(lpArgumentString);
  356. if ( pvAddr ) {
  357. //
  358. // get the tree
  359. //
  360. SCEP_SPLAY_TREE tree;
  361. memset(&tree, '\0', sizeof(SCEP_SPLAY_TREE));
  362. GET_DATA(pvAddr, (PVOID)&tree, sizeof(SCEP_SPLAY_TREE) );
  363. DebuggerOut("Splay Tree @%p:\n", pvAddr);
  364. DebuggerOut("\tSplay nodes @%p\tSentinel @%p\t", tree.Root, tree.Sentinel);
  365. switch ( tree.Type ) {
  366. case SplayNodeSidType:
  367. DebuggerOut("SID Type\n");
  368. break;
  369. case SplayNodeStringType:
  370. DebuggerOut("String Type\n");
  371. break;
  372. default:
  373. DebuggerOut("Invalid Type\n");
  374. //
  375. // can't go further
  376. //
  377. return;
  378. }
  379. if ( tree.Root != tree.Sentinel ) {
  380. SceExtspDumpSplayNodes(tree.Root, tree.Sentinel, tree.Type);
  381. } else {
  382. DebuggerOut("\tSplay tree is empty\n");
  383. }
  384. } else {
  385. DebuggerOut("Can't get splay tree address\n");
  386. }
  387. } else {
  388. DebuggerOut("No address specified.\n");
  389. }
  390. }
  391. VOID
  392. DumpScePolicyQueue(
  393. HANDLE hCurrentProcess,
  394. HANDLE hCurrentThread,
  395. DWORD dwCurrentPc,
  396. PNTSD_EXTENSION_APIS lpExtensionApis,
  397. LPSTR lpArgumentString
  398. )
  399. /*++
  400. Routine Description:
  401. Dump policy notification queue status and nodes.
  402. Arguments:
  403. hCurrentProcess - Handle for the process being debugged.
  404. hCurrentThread - Handle for the thread that has the debugger focus.
  405. dwCurrentPc - Current Program Counter?
  406. lpExtensionApis - Pointer to a structure that contains pointers to
  407. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  408. typedef struct _NTSD_EXTENSION_APIS {
  409. DWORD nSize;
  410. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  411. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  412. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  413. PNTSD_DISASM lpDisasmRoutine;
  414. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  415. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  416. lpArgumentString - This is a pointer to a string that contains
  417. space seperated arguments that are passed to debugger
  418. extension function.
  419. Return Value:
  420. none
  421. --*/
  422. {
  423. PVOID pvAddr;
  424. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  425. //
  426. // get queue node address
  427. //
  428. if (lpArgumentString && *lpArgumentString != '\0' )
  429. {
  430. pvAddr = (PVOID)(lpGetExpressionRoutine)(lpArgumentString);
  431. if ( pvAddr ) {
  432. SceExtspDumpQueueNode(pvAddr, TRUE); // one node only
  433. } else {
  434. DebuggerOut("\tCan't get queue node address from %s\n", lpArgumentString);
  435. }
  436. return;
  437. }
  438. //
  439. // dump policy queue and globals
  440. // First get the address of queue globals
  441. //
  442. DebuggerOut("Policy queue status:\n");
  443. DWORD dwValue=0;
  444. GET_DWORD( SCEEXTS_POLICY_QUEUE_LOG);
  445. if ( dwValue != (DWORD)-1 ) {
  446. switch ( dwValue ) {
  447. case 0:
  448. // do not log anything
  449. DebuggerOut("\t@%p Logging (0) - no log\n", pvAddr);
  450. break;
  451. case 1:
  452. // log error only
  453. DebuggerOut("\t@%p Logging (1) - error logging only\n", pvAddr);
  454. break;
  455. default:
  456. DebuggerOut("\t@%p Logging (%d) - verbose log\n", pvAddr, dwValue);
  457. break;
  458. }
  459. }
  460. GET_DWORD(SCEEXTS_POLICY_QUEUE_PRODUCT_QUERY);
  461. if ( dwValue > 0 && dwValue != (DWORD)-1) {
  462. GET_DWORD(SCEEXTS_POLICY_QUEUE_PRODUCT);
  463. switch ( dwValue ) {
  464. case NtProductWinNt:
  465. DebuggerOut("\t@%p Product Type (%d)- professional\n", pvAddr, dwValue);
  466. break;
  467. case NtProductLanManNt:
  468. DebuggerOut("\t@%p Product Type (%d) - Domain Controller\n", pvAddr, dwValue);
  469. break;
  470. case NtProductServer:
  471. DebuggerOut("\t@%p Product Type (%d) - Server\n", pvAddr, dwValue);
  472. break;
  473. default:
  474. DebuggerOut("\t@%p Unknown Product Type (%d)\n", pvAddr, dwValue);
  475. break;
  476. }
  477. } else if (dwValue != (DWORD)-1) {
  478. DebuggerOut("\t@%p Unknown Product Type\n", pvAddr);
  479. }
  480. GET_DWORD(SCEEXTS_POLICY_QUEUE_SUSPEND);
  481. if ( dwValue > 0 && dwValue != (DWORD)-1) {
  482. DebuggerOut("\t@%p Queue is suspended\n", pvAddr);
  483. } else if (dwValue != (DWORD)-1) {
  484. DebuggerOut("\t@%p Queue is not suspended\n\n", pvAddr);
  485. }
  486. DebuggerOut("Policy queue data:\n");
  487. PVOID pvHead = (PVOID)(lpGetExpressionRoutine)(SCEEXTS_POLICY_QUEUE_HEAD);
  488. PVOID pvTail = (PVOID)(lpGetExpressionRoutine)(SCEEXTS_POLICY_QUEUE_TAIL);
  489. GET_DWORD(SCEEXTS_POLICY_QUEUE_COUNT);
  490. PVOID pvNumNodes = pvAddr;
  491. DWORD NumNodes=dwValue;
  492. GET_DWORD(SCEEXTS_POLICY_QUEUE_RETRY);
  493. PVOID pvRetry = pvAddr;
  494. DWORD RetryNodes=dwValue;
  495. DebuggerOut("\tHead @%p, Tail @%p, Count (@%p) %d, Retry Count (@%p) %d\n", pvHead, pvTail, pvNumNodes, pvRetry, NumNodes, RetryNodes);
  496. if ( pvHead != NULL ) {
  497. PVOID pHead=NULL;
  498. GET_DATA(pvHead, (LPVOID)&pHead, sizeof(PVOID));
  499. if ( pHead ) {
  500. SceExtspDumpQueueNode(pHead, FALSE);
  501. } else {
  502. DebuggerOut("\t Queue is empty\n");
  503. }
  504. }
  505. }
  506. VOID
  507. DumpSceServerState(
  508. HANDLE hCurrentProcess,
  509. HANDLE hCurrentThread,
  510. DWORD dwCurrentPc,
  511. PNTSD_EXTENSION_APIS lpExtensionApis,
  512. LPSTR lpArgumentString
  513. )
  514. /*++
  515. Routine Description:
  516. Dump SCERPC server state.
  517. Arguments:
  518. hCurrentProcess - Handle for the process being debugged.
  519. hCurrentThread - Handle for the thread that has the debugger focus.
  520. dwCurrentPc - Current Program Counter?
  521. lpExtensionApis - Pointer to a structure that contains pointers to
  522. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  523. typedef struct _NTSD_EXTENSION_APIS {
  524. DWORD nSize;
  525. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  526. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  527. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  528. PNTSD_DISASM lpDisasmRoutine;
  529. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  530. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  531. lpArgumentString - This is a pointer to a string that contains
  532. space seperated arguments that are passed to debugger
  533. extension function.
  534. Return Value:
  535. none
  536. --*/
  537. {
  538. PVOID pvAddr;
  539. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  540. DebuggerOut("SCE server state:\n");
  541. //
  542. // check JET engine is running or not
  543. //
  544. DWORD dwValue=0;
  545. GET_DWORD( SCEEXTS_SERVER_JET_INIT);
  546. if ( dwValue != (DWORD)-1 ) {
  547. if ( dwValue ) {
  548. GET_DWORD( SCEEXTS_SERVER_JET_INSTANCE );
  549. DebuggerOut("\tJet engine is initialized, JetInstance=%x\n", dwValue);
  550. } else {
  551. DebuggerOut("\tJet engine is not initialized\n");
  552. }
  553. }
  554. PVOID pvPtr=NULL;
  555. DebuggerOut("\tAll open Jet database contexts:\n");
  556. pvAddr = (PVOID)(lpGetExpressionRoutine)( SCEEXTS_SERVER_OPEN_CONTEXT);
  557. if ( pvAddr ) {
  558. GET_DATA ( pvAddr, (LPVOID)&pvPtr, sizeof(PVOID) );
  559. if ( pvPtr ) {
  560. SCESRV_CONTEXT_LIST OpenContext;
  561. while ( pvPtr ) {
  562. memset(&OpenContext, '\0', sizeof(SCESRV_CONTEXT_LIST));
  563. GET_DATA ( pvPtr, (LPVOID)&OpenContext, sizeof(SCESRV_CONTEXT_LIST));
  564. DebuggerOut("\t\tThis @%p, JetContext @%p, Next @%p, Prior @%p\n", pvPtr,
  565. OpenContext.Context, OpenContext.Next, OpenContext.Prior);
  566. pvPtr = (PVOID)(OpenContext.Next);
  567. }
  568. } else {
  569. DebuggerOut("\t\tNo active open context.\n");
  570. }
  571. } else {
  572. DebuggerOut("\t\tFail to get the address of %s\n", SCEEXTS_SERVER_OPEN_CONTEXT);
  573. }
  574. DebuggerOut("\tAll active database operations:\n");
  575. pvAddr = (PVOID)(lpGetExpressionRoutine)( SCEEXTS_SERVER_DB_CONTEXT);
  576. if ( pvAddr ) {
  577. GET_DATA ( pvAddr, (LPVOID)&pvPtr, sizeof(PVOID) );
  578. if ( pvPtr ) {
  579. SCESRV_DBTASK DbTask;
  580. while ( pvPtr ) {
  581. memset(&DbTask, '\0', sizeof(SCESRV_DBTASK));
  582. GET_DATA ( pvPtr, (LPVOID)&DbTask, sizeof(SCESRV_DBTASK));
  583. DebuggerOut("\t\tThis @%p, JetContext @%p, In Use %d, In close %d, Next @%p, Prior @%p\n", pvPtr,
  584. DbTask.Context, DbTask.dInUsed, DbTask.bCloseReq, DbTask.Next, DbTask.Prior);
  585. pvPtr = (PVOID)(DbTask.Next);
  586. }
  587. } else {
  588. DebuggerOut("\t\tNo active database operation.\n");
  589. }
  590. } else {
  591. DebuggerOut("\t\tFail to get the address of %s\n", SCEEXTS_SERVER_DB_CONTEXT);
  592. }
  593. DebuggerOut("\tAll engine task (configuration/analysis):\n");
  594. pvAddr = (PVOID)(lpGetExpressionRoutine)( SCEEXTS_SERVER_ENGINE);
  595. if ( pvAddr ) {
  596. GET_DATA ( pvAddr, (LPVOID)&pvPtr, sizeof(PVOID) );
  597. if ( pvPtr ) {
  598. SCESRV_ENGINE EngineTask;
  599. WCHAR DbName[1024];
  600. while ( pvPtr ) {
  601. memset(&EngineTask, '\0', sizeof(SCESRV_ENGINE));
  602. GET_DATA ( pvPtr, (LPVOID)&EngineTask, sizeof(SCESRV_ENGINE));
  603. DbName[0] = L'\0';
  604. if ( EngineTask.Database ) {
  605. GET_STRING( (LPWSTR)(EngineTask.Database), DbName, 1024);
  606. }
  607. DebuggerOut("\t\tThis @%p, Next @%p, Prior @%p\n", pvPtr, EngineTask.Next, EngineTask.Prior);
  608. DebuggerOut("\t\t On database : %ws\n", DbName);
  609. pvPtr = (PVOID)(EngineTask.Next);
  610. }
  611. } else {
  612. DebuggerOut("\t\tNo active configuration/anslysis operation.\n");
  613. }
  614. } else {
  615. DebuggerOut("\t\tFail to get the address of %s\n", SCEEXTS_SERVER_ENGINE);
  616. }
  617. DebuggerOut("\n");
  618. }
  619. VOID
  620. DumpSceSetupDcpromoState(
  621. HANDLE hCurrentProcess,
  622. HANDLE hCurrentThread,
  623. DWORD dwCurrentPc,
  624. PNTSD_EXTENSION_APIS lpExtensionApis,
  625. LPSTR lpArgumentString
  626. )
  627. /*++
  628. Routine Description:
  629. Dump SCE status in setup or dcpromo.
  630. Arguments:
  631. hCurrentProcess - Handle for the process being debugged.
  632. hCurrentThread - Handle for the thread that has the debugger focus.
  633. dwCurrentPc - Current Program Counter?
  634. lpExtensionApis - Pointer to a structure that contains pointers to
  635. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  636. typedef struct _NTSD_EXTENSION_APIS {
  637. DWORD nSize;
  638. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  639. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  640. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  641. PNTSD_DISASM lpDisasmRoutine;
  642. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  643. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  644. lpArgumentString - This is a pointer to a string that contains
  645. space seperated arguments that are passed to debugger
  646. extension function.
  647. Return Value:
  648. none
  649. --*/
  650. {
  651. PVOID pvAddr;
  652. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  653. DebuggerOut("SCE setup/dcpromo status:\n");
  654. pvAddr = (PVOID)(lpGetExpressionRoutine)( SCEEXTS_CLIENT_SETUPDB);
  655. if ( pvAddr ) {
  656. PVOID pvPtr=NULL;
  657. GET_DATA(pvAddr, (LPVOID)&pvPtr, sizeof(PVOID));
  658. if ( pvPtr ) {
  659. DebuggerOut("\tSecurity database handle @%p\n", pvPtr);
  660. } else {
  661. DebuggerOut("\tSecurity database is not opened\n");
  662. }
  663. } else {
  664. DebuggerOut("\tFail to get address of %s\n", SCEEXTS_CLIENT_SETUPDB);
  665. }
  666. DWORD dwValue;
  667. GET_DWORD(SCEEXTS_CLIENT_ISNT5);
  668. if ( dwValue != (DWORD)-1 ) {
  669. if ( dwValue ) {
  670. DebuggerOut("\tSetup for Windows 2000 or newer\n");
  671. } else {
  672. DebuggerOut("\tUpgrade from NT 4.0 or older\n");
  673. }
  674. }
  675. GET_DWORD(SCEEXTS_CLIENT_PRODUCT);
  676. if ( dwValue != (DWORD)-1 ) {
  677. switch ( dwValue ) {
  678. case NtProductWinNt:
  679. DebuggerOut("\tProduct Type (%d)- professional\n", dwValue);
  680. break;
  681. case NtProductLanManNt:
  682. DebuggerOut("\tProduct Type (%d) - Domain Controller\n", dwValue);
  683. break;
  684. case NtProductServer:
  685. DebuggerOut("\tProduct Type (%d) - Server\n", dwValue);
  686. break;
  687. default:
  688. DebuggerOut("\tUnknown Product Type (%d)\n", dwValue);
  689. break;
  690. }
  691. }
  692. pvAddr = (PVOID)(lpGetExpressionRoutine)( SCEEXTS_CLIENT_PREFIX);
  693. WCHAR szName[MAX_PATH*2+1];
  694. if ( pvAddr ) {
  695. memset(szName, '\0', MAX_PATH*2+1);
  696. GET_STRING( (PWSTR)pvAddr, szName, MAX_PATH*2);
  697. DebuggerOut("\tCallback prefix: %ws\n", szName);
  698. } else {
  699. DebuggerOut("\tFail to get address of %s\n", SCEEXTS_CLIENT_PREFIX);
  700. }
  701. pvAddr = (PVOID)(lpGetExpressionRoutine)( SCEEXTS_CLIENT_UPD_FILE);
  702. if ( pvAddr ) {
  703. memset(szName, '\0', MAX_PATH*2+1);
  704. GET_STRING( (PWSTR)pvAddr, szName, MAX_PATH*2);
  705. DebuggerOut("\tUpgrade file name: %ws\n", szName);
  706. } else {
  707. DebuggerOut("\tFail to get address of %s\n", SCEEXTS_CLIENT_UPD_FILE);
  708. }
  709. }
  710. VOID
  711. DumpScePolicyNotification(
  712. HANDLE hCurrentProcess,
  713. HANDLE hCurrentThread,
  714. DWORD dwCurrentPc,
  715. PNTSD_EXTENSION_APIS lpExtensionApis,
  716. LPSTR lpArgumentString
  717. )
  718. /*++
  719. Routine Description:
  720. Dump SCE client notification (from LSA or SAM).
  721. Arguments:
  722. hCurrentProcess - Handle for the process being debugged.
  723. hCurrentThread - Handle for the thread that has the debugger focus.
  724. dwCurrentPc - Current Program Counter?
  725. lpExtensionApis - Pointer to a structure that contains pointers to
  726. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  727. typedef struct _NTSD_EXTENSION_APIS {
  728. DWORD nSize;
  729. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  730. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  731. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  732. PNTSD_DISASM lpDisasmRoutine;
  733. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  734. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  735. lpArgumentString - This is a pointer to a string that contains
  736. space seperated arguments that are passed to debugger
  737. extension function.
  738. Return Value:
  739. none
  740. --*/
  741. {
  742. PVOID pvAddr;
  743. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  744. DWORD dwValue;
  745. DebuggerOut("Policy Notification state:\n");
  746. GET_DWORD(SCEEXTS_CLIENT_NOTIFY_ROLEQUERY);
  747. if ( dwValue != (DWORD)-1 ) {
  748. if ( dwValue > 0 ) {
  749. GET_DWORD(SCEEXTS_CLIENT_NOTIFY_ROLE);
  750. if ( dwValue != (DWORD)-1 ) {
  751. switch ( dwValue ) {
  752. case DsRole_RoleStandaloneWorkstation:
  753. DebuggerOut("\tMachine Role: standalone professional\n");
  754. break;
  755. case DsRole_RoleMemberWorkstation:
  756. DebuggerOut("\tMachine Role: member workstation\n");
  757. break;
  758. case DsRole_RoleStandaloneServer:
  759. DebuggerOut("\tMachine Role: standalone server\n");
  760. break;
  761. case DsRole_RoleMemberServer:
  762. DebuggerOut("\tMachine Role: member server\n");
  763. break;
  764. case DsRole_RoleBackupDomainController:
  765. DebuggerOut("\tMachine Role: domain controller replica\n");
  766. break;
  767. case DsRole_RolePrimaryDomainController:
  768. DebuggerOut("\tMachine Role: primary domain controller\n");
  769. break;
  770. default:
  771. DebuggerOut("\tUnknown machine role\n");
  772. break;
  773. }
  774. }
  775. GET_DWORD(SCEEXTS_CLIENT_NOTIFY_ROLEFLAG);
  776. if ( dwValue != (DWORD)-1 ) {
  777. DebuggerOut("\tMachine Role Flag %x\n", dwValue);
  778. }
  779. } else {
  780. DebuggerOut("\tMachine role has not been queried\n");
  781. }
  782. }
  783. GET_DWORD(SCEEXTS_CLIENT_NOTIFY_ACTIVE);
  784. if ( dwValue != (DWORD)-1 ) {
  785. if ( dwValue > 0 ) {
  786. DebuggerOut("\tNotification thread active\n");
  787. } else {
  788. DebuggerOut("\tNotification thread is not active\n");
  789. }
  790. }
  791. GET_DWORD(SCEEXTS_CLIENT_NOTIFY_COUNT);
  792. if ( dwValue != (DWORD)-1 ) {
  793. DebuggerOut("\tCurrent notification count %d\n", dwValue);
  794. }
  795. DebuggerOut("\tCurrent notifications:\n");
  796. pvAddr = (PVOID)(lpGetExpressionRoutine)( SCEEXTS_CLIENT_NOTIFY_LIST);
  797. if ( pvAddr ) {
  798. SCEP_NOTIFYARGS_NODE ListNode;
  799. LIST_ENTRY MyList;
  800. memset(&MyList, '\0', sizeof(LIST_ENTRY));
  801. GET_DATA( pvAddr, (LPVOID)&MyList, sizeof(LIST_ENTRY) );
  802. if ( MyList.Flink == pvAddr ) {
  803. DebuggerOut("\t List is empty\n");
  804. } else {
  805. PVOID pvPtr = (LPVOID)MyList.Flink;
  806. while ( pvPtr != pvAddr ) {
  807. memset(&ListNode, '\0', sizeof(SCEP_NOTIFYARGS_NODE));
  808. GET_DATA( pvPtr, (LPVOID)&ListNode, sizeof(SCEP_NOTIFYARGS_NODE));
  809. DebuggerOut("\tThis Node @%p, Flink @%p, Blink @%p\n", pvPtr, ListNode.List.Flink, ListNode.List.Blink);
  810. SceExtspDumpNotificationInfo(ListNode.DbType, ListNode.ObjectType, ListNode.DeltaType);
  811. if ( ListNode.ObjectSid ) {
  812. SceExtspReadDumpSID("\t",ListNode.ObjectSid);
  813. } else {
  814. DebuggerOut("\n");
  815. }
  816. pvPtr = (PVOID)(ListNode.List.Flink);
  817. }
  818. }
  819. } else {
  820. DebuggerOut("\t Fail to get address of %s\n", SCEEXTS_CLIENT_NOTIFY_LIST);
  821. }
  822. }
  823. VOID
  824. DumpScePolicyPropStatus(
  825. HANDLE hCurrentProcess,
  826. HANDLE hCurrentThread,
  827. DWORD dwCurrentPc,
  828. PNTSD_EXTENSION_APIS lpExtensionApis,
  829. LPSTR lpArgumentString
  830. )
  831. /*++
  832. Routine Description:
  833. Dump SCE client notification (from LSA or SAM).
  834. Arguments:
  835. hCurrentProcess - Handle for the process being debugged.
  836. hCurrentThread - Handle for the thread that has the debugger focus.
  837. dwCurrentPc - Current Program Counter?
  838. lpExtensionApis - Pointer to a structure that contains pointers to
  839. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  840. typedef struct _NTSD_EXTENSION_APIS {
  841. DWORD nSize;
  842. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  843. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  844. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  845. PNTSD_DISASM lpDisasmRoutine;
  846. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  847. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  848. lpArgumentString - This is a pointer to a string that contains
  849. space seperated arguments that are passed to debugger
  850. extension function.
  851. Return Value:
  852. none
  853. --*/
  854. {
  855. PVOID pvAddr;
  856. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  857. DWORD dwValue;
  858. DebuggerOut("Policy propagation status:\n");
  859. GET_DWORD(SCEEXTS_CLIENT_POLICY_DCQUERY);
  860. if ( dwValue != (DWORD)-1 ) {
  861. if ( dwValue ) {
  862. GET_DWORD(SCEEXTS_CLIENT_POLICY_ISDC);
  863. if ( dwValue ) {
  864. DebuggerOut("\tMachine is a DC\n");
  865. } else {
  866. DebuggerOut("\tMachine is not a DC\n");
  867. }
  868. } else {
  869. DebuggerOut("\tMachine role is not queried\n");
  870. }
  871. }
  872. GET_DWORD(SCEEXTS_CLIENT_POLICY_ASYNC);
  873. if ( dwValue != (DWORD)-1 ) {
  874. if ( dwValue ) {
  875. DebuggerOut("\tPolicy propagation runs in asynchronous mode\n");
  876. } else {
  877. DebuggerOut("\tPolicy propagation runs in synchronous mode\n");
  878. }
  879. }
  880. GET_DWORD(SCEEXTS_CLIENT_POLICY_HRSRSOP);
  881. if ( dwValue != (DWORD)-1 ) {
  882. DebuggerOut("\tSynchronous mode status code %x\n", dwValue);
  883. }
  884. GET_DWORD(SCEEXTS_CLIENT_POLICY_HRARSOP);
  885. if ( dwValue != (DWORD)-1 ) {
  886. DebuggerOut("\tAsynchronous mode status code %x\n", dwValue);
  887. }
  888. }
  889. VOID
  890. DumpSceNameList(
  891. HANDLE hCurrentProcess,
  892. HANDLE hCurrentThread,
  893. DWORD dwCurrentPc,
  894. PNTSD_EXTENSION_APIS lpExtensionApis,
  895. LPSTR lpArgumentString
  896. )
  897. /*++
  898. Routine Description:
  899. Dump SCE_NAME_LIST structure.
  900. Arguments:
  901. hCurrentProcess - Handle for the process being debugged.
  902. hCurrentThread - Handle for the thread that has the debugger focus.
  903. dwCurrentPc - Current Program Counter?
  904. lpExtensionApis - Pointer to a structure that contains pointers to
  905. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  906. typedef struct _NTSD_EXTENSION_APIS {
  907. DWORD nSize;
  908. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  909. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  910. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  911. PNTSD_DISASM lpDisasmRoutine;
  912. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  913. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  914. lpArgumentString - This is a pointer to a string that contains
  915. space seperated arguments that are passed to debugger
  916. extension function.
  917. Return Value:
  918. none
  919. --*/
  920. {
  921. PVOID pvAddr;
  922. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  923. if (lpArgumentString && *lpArgumentString != '\0' )
  924. {
  925. pvAddr = (PVOID)(lpGetExpressionRoutine)(lpArgumentString);
  926. if ( pvAddr ) {
  927. DebuggerOut("Names in list @%p\n", pvAddr);
  928. SceExtspReadDumpNameList(pvAddr, "\t");
  929. } else {
  930. DebuggerOut("\tCan't get address\n");
  931. }
  932. } else {
  933. DebuggerOut("No address specified\n");
  934. }
  935. }
  936. VOID
  937. DumpSceNameStatusList(
  938. HANDLE hCurrentProcess,
  939. HANDLE hCurrentThread,
  940. DWORD dwCurrentPc,
  941. PNTSD_EXTENSION_APIS lpExtensionApis,
  942. LPSTR lpArgumentString
  943. )
  944. /*++
  945. Routine Description:
  946. Dump SCE_NAME_STATUS_LIST structure.
  947. Arguments:
  948. hCurrentProcess - Handle for the process being debugged.
  949. hCurrentThread - Handle for the thread that has the debugger focus.
  950. dwCurrentPc - Current Program Counter?
  951. lpExtensionApis - Pointer to a structure that contains pointers to
  952. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  953. typedef struct _NTSD_EXTENSION_APIS {
  954. DWORD nSize;
  955. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  956. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  957. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  958. PNTSD_DISASM lpDisasmRoutine;
  959. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  960. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  961. lpArgumentString - This is a pointer to a string that contains
  962. space seperated arguments that are passed to debugger
  963. extension function.
  964. Return Value:
  965. none
  966. --*/
  967. {
  968. PVOID pvAddr;
  969. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  970. if (lpArgumentString && *lpArgumentString != '\0' )
  971. {
  972. pvAddr = (PVOID)(lpGetExpressionRoutine)(lpArgumentString);
  973. if ( pvAddr ) {
  974. DebuggerOut("Names/status in list @%p\n", pvAddr);
  975. SCE_NAME_STATUS_LIST List;
  976. WCHAR Name[1024];
  977. while ( pvAddr != NULL ) {
  978. memset(&List, '\0', sizeof(SCE_NAME_STATUS_LIST));
  979. GET_DATA(pvAddr, (LPVOID)&List, sizeof(SCE_NAME_STATUS_LIST));
  980. Name[0] = L'\0';
  981. if ( List.Name != NULL )
  982. GET_STRING(List.Name, Name, 1024);
  983. DebuggerOut("\t(@%p, Next @%p) Status %d, %ws\n", List.Name, List.Next, List.Status, Name);
  984. pvAddr = List.Next;
  985. }
  986. } else {
  987. DebuggerOut("\tCan't get address\n");
  988. }
  989. } else {
  990. DebuggerOut("No address specified\n");
  991. }
  992. }
  993. VOID
  994. DumpSceADLTable(
  995. HANDLE hCurrentProcess,
  996. HANDLE hCurrentThread,
  997. DWORD dwCurrentPc,
  998. PNTSD_EXTENSION_APIS lpExtensionApis,
  999. LPSTR lpArgumentString
  1000. )
  1001. /*++
  1002. Routine Description:
  1003. Dump SCEP_ADL_NODE table (with size SCEP_ADL_HTABLE_SIZE).
  1004. Arguments:
  1005. hCurrentProcess - Handle for the process being debugged.
  1006. hCurrentThread - Handle for the thread that has the debugger focus.
  1007. dwCurrentPc - Current Program Counter?
  1008. lpExtensionApis - Pointer to a structure that contains pointers to
  1009. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  1010. typedef struct _NTSD_EXTENSION_APIS {
  1011. DWORD nSize;
  1012. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  1013. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  1014. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  1015. PNTSD_DISASM lpDisasmRoutine;
  1016. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1017. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  1018. lpArgumentString - This is a pointer to a string that contains
  1019. space seperated arguments that are passed to debugger
  1020. extension function.
  1021. Return Value:
  1022. none
  1023. --*/
  1024. {
  1025. PVOID pvAddr;
  1026. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  1027. if (lpArgumentString && *lpArgumentString != '\0' )
  1028. {
  1029. pvAddr = (PVOID)(lpGetExpressionRoutine)(lpArgumentString);
  1030. if ( pvAddr ) {
  1031. DebuggerOut("ADL table start at @%p\n", pvAddr);
  1032. PVOID Table[SCEP_ADL_HTABLE_SIZE];
  1033. GET_DATA(pvAddr, (PVOID)&Table, sizeof(PVOID)*SCEP_ADL_HTABLE_SIZE);
  1034. for ( int i=0; i<SCEP_ADL_HTABLE_SIZE; i++) {
  1035. if ( Table[i] ) {
  1036. DebuggerOut("\tIndex %d",i);
  1037. SceExtspDumpADLNodes(Table[i]);
  1038. }
  1039. }
  1040. } else {
  1041. DebuggerOut("\tCan't get address of ADL table.\n");
  1042. }
  1043. } else {
  1044. DebuggerOut("No address specified.\n");
  1045. }
  1046. }
  1047. VOID
  1048. DumpSceADLNodes(
  1049. HANDLE hCurrentProcess,
  1050. HANDLE hCurrentThread,
  1051. DWORD dwCurrentPc,
  1052. PNTSD_EXTENSION_APIS lpExtensionApis,
  1053. LPSTR lpArgumentString
  1054. )
  1055. /*++
  1056. Routine Description:
  1057. Dump SCEP_ADL_NODE structure.
  1058. Arguments:
  1059. hCurrentProcess - Handle for the process being debugged.
  1060. hCurrentThread - Handle for the thread that has the debugger focus.
  1061. dwCurrentPc - Current Program Counter?
  1062. lpExtensionApis - Pointer to a structure that contains pointers to
  1063. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  1064. typedef struct _NTSD_EXTENSION_APIS {
  1065. DWORD nSize;
  1066. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  1067. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  1068. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  1069. PNTSD_DISASM lpDisasmRoutine;
  1070. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1071. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  1072. lpArgumentString - This is a pointer to a string that contains
  1073. space seperated arguments that are passed to debugger
  1074. extension function.
  1075. Return Value:
  1076. none
  1077. --*/
  1078. {
  1079. PVOID pvAddr;
  1080. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  1081. if (lpArgumentString && *lpArgumentString != '\0' )
  1082. {
  1083. pvAddr = (PVOID)(lpGetExpressionRoutine)(lpArgumentString);
  1084. if ( pvAddr ) {
  1085. DebuggerOut("ADL Nodes start at @%p\n", pvAddr);
  1086. SceExtspDumpADLNodes(pvAddr);
  1087. } else {
  1088. DebuggerOut("\tCan't get address of the ADL nodes.\n");
  1089. }
  1090. } else {
  1091. DebuggerOut("No address specified.\n");
  1092. }
  1093. }
  1094. VOID
  1095. DumpSceObjectTree(
  1096. HANDLE hCurrentProcess,
  1097. HANDLE hCurrentThread,
  1098. DWORD dwCurrentPc,
  1099. PNTSD_EXTENSION_APIS lpExtensionApis,
  1100. LPSTR lpArgumentString
  1101. )
  1102. /*++
  1103. Routine Description:
  1104. Dump SCEP_OBJECT_TREE structure.
  1105. Arguments:
  1106. hCurrentProcess - Handle for the process being debugged.
  1107. hCurrentThread - Handle for the thread that has the debugger focus.
  1108. dwCurrentPc - Current Program Counter?
  1109. lpExtensionApis - Pointer to a structure that contains pointers to
  1110. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  1111. typedef struct _NTSD_EXTENSION_APIS {
  1112. DWORD nSize;
  1113. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  1114. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  1115. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  1116. PNTSD_DISASM lpDisasmRoutine;
  1117. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1118. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  1119. lpArgumentString - This is a pointer to a string that contains
  1120. space seperated arguments that are passed to debugger
  1121. extension function.
  1122. -r <ChildLevel> -m <ChildCount> -n <StartName> -s <Address>
  1123. Return Value:
  1124. none
  1125. --*/
  1126. {
  1127. PVOID pvAddr;
  1128. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  1129. if (lpArgumentString && *lpArgumentString != '\0' )
  1130. {
  1131. LPSTR szCommand = lpArgumentString;
  1132. LPSTR ThisArg, szValue;
  1133. LPSTR pszAddr=NULL;
  1134. DWORD Len;
  1135. DWORD Level=0;
  1136. DWORD Count=0;
  1137. WCHAR wszName[MAX_PATH];
  1138. BOOL bDumpSD = FALSE;
  1139. wszName[0] = L'\0';
  1140. SceExtspGetNextArgument(&szCommand, &ThisArg, &Len);
  1141. if ( ThisArg && Len > 0 ) {
  1142. do {
  1143. if ( *ThisArg != '-' ) {
  1144. //
  1145. // this is the address
  1146. //
  1147. if ( pszAddr == NULL )
  1148. pszAddr = ThisArg;
  1149. else {
  1150. DebuggerOut("duplicate addr %s\n", ThisArg);
  1151. return;
  1152. }
  1153. } else if ( Len == 2 &&
  1154. ( *(ThisArg+1) == 'r' ||
  1155. *(ThisArg+1) == 'm' ||
  1156. *(ThisArg+1) == 'n' ) ) {
  1157. SceExtspGetNextArgument(&szCommand, &szValue, &Len);
  1158. if ( szValue && Len > 0 ) {
  1159. switch ( *(ThisArg+1) ) {
  1160. case 'r':
  1161. Level = atoi(szValue);
  1162. break;
  1163. case 'm':
  1164. Count = atoi(szValue);
  1165. break;
  1166. case 'n':
  1167. if ( Len < MAX_PATH ) {
  1168. ULONG Index;
  1169. RtlMultiByteToUnicodeN(
  1170. wszName,
  1171. (MAX_PATH-1)*2,
  1172. &Index,
  1173. szValue,
  1174. Len
  1175. );
  1176. wszName[MAX_PATH] = L'\0';
  1177. } else {
  1178. DebuggerOut("Name too long for argument -n \n");
  1179. return;
  1180. }
  1181. break;
  1182. }
  1183. } else {
  1184. DebuggerOut("Invalid arguments\n");
  1185. return;
  1186. }
  1187. } else if ( Len == 2 &&
  1188. ( *(ThisArg+1) == 's' ) ) {
  1189. bDumpSD = TRUE;
  1190. } else {
  1191. DebuggerOut("Invalid options\n");
  1192. return;
  1193. }
  1194. SceExtspGetNextArgument(&szCommand, &ThisArg, &Len);
  1195. if ( ThisArg == NULL ) {
  1196. break;
  1197. }
  1198. } while ( *szCommand != '\0' || ThisArg );
  1199. } else {
  1200. DebuggerOut("No argument\n");
  1201. return;
  1202. }
  1203. if ( pszAddr == NULL ) {
  1204. DebuggerOut("No address specified.\n");
  1205. } else {
  1206. //
  1207. // get the object tree address
  1208. //
  1209. pvAddr = (PVOID)(lpGetExpressionRoutine)(pszAddr);
  1210. if ( pvAddr ) {
  1211. DebuggerOut("Object tree at @%p\n", pvAddr);
  1212. if ( (Count > 0 || wszName[0] != L'\0') && Level != 1) {
  1213. DebuggerOut("\tOnly one level is allowed\n");
  1214. Level = 1;
  1215. } else {
  1216. if ( Level > 0 )
  1217. DebuggerOut("\tRecursive Level %d.", Level);
  1218. else
  1219. DebuggerOut("\tAll levels.");
  1220. }
  1221. if ( Count > 0 )
  1222. DebuggerOut("\tMaximum Children returned %d.", Count);
  1223. else
  1224. DebuggerOut("\tAll children.");
  1225. if ( wszName[0] != L'\0' )
  1226. DebuggerOut("\tStart at child %ws.\n", wszName);
  1227. else
  1228. DebuggerOut("\tStart at first child.\n");
  1229. if ( bDumpSD )
  1230. DebuggerOut("\tDump security descriptor.\n");
  1231. else
  1232. DebuggerOut("\tDo not dump security descriptor.\n");
  1233. SceExtspDumpObjectTree(pvAddr, Level, Count, wszName, bDumpSD );
  1234. } else {
  1235. DebuggerOut("Can't get address of the object tree.\n");
  1236. }
  1237. }
  1238. } else {
  1239. DebuggerOut("No argument specified.\n");
  1240. }
  1241. }
  1242. VOID
  1243. DumpScePrivilegeValueList(
  1244. HANDLE hCurrentProcess,
  1245. HANDLE hCurrentThread,
  1246. DWORD dwCurrentPc,
  1247. PNTSD_EXTENSION_APIS lpExtensionApis,
  1248. LPSTR lpArgumentString
  1249. )
  1250. /*++
  1251. Routine Description:
  1252. Dump SCE_PRIVILEGE_VALUE_LIST structure.
  1253. Arguments:
  1254. hCurrentProcess - Handle for the process being debugged.
  1255. hCurrentThread - Handle for the thread that has the debugger focus.
  1256. dwCurrentPc - Current Program Counter?
  1257. lpExtensionApis - Pointer to a structure that contains pointers to
  1258. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  1259. typedef struct _NTSD_EXTENSION_APIS {
  1260. DWORD nSize;
  1261. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  1262. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  1263. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  1264. PNTSD_DISASM lpDisasmRoutine;
  1265. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1266. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  1267. lpArgumentString - This is a pointer to a string that contains
  1268. space seperated arguments that are passed to debugger
  1269. extension function.
  1270. Return Value:
  1271. none
  1272. --*/
  1273. {
  1274. PVOID pvAddr;
  1275. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  1276. if (lpArgumentString && *lpArgumentString != '\0' )
  1277. {
  1278. pvAddr = (PVOID)(lpGetExpressionRoutine)(lpArgumentString);
  1279. if ( pvAddr ) {
  1280. DebuggerOut("Privilege value list @%p\n", pvAddr);
  1281. SCE_PRIVILEGE_VALUE_LIST List;
  1282. WCHAR Name[MAX_PATH];
  1283. while ( pvAddr != NULL ) {
  1284. memset(&List, '\0', sizeof(SCE_PRIVILEGE_VALUE_LIST));
  1285. GET_DATA(pvAddr, (LPVOID)&List, sizeof(SCE_PRIVILEGE_VALUE_LIST));
  1286. DebuggerOut("\t(@%p, Next @%p) Privs %08x08x, ", pvAddr, List.Next, List.PrivHighPart, List.PrivLowPart);
  1287. Name[0] = L'\0';
  1288. if ( List.Name != NULL ) {
  1289. GET_DATA((PVOID)(List.Name), (PVOID)Name, MAX_PATH*2);
  1290. if ( RtlValidSid ( (PSID)Name ) ) {
  1291. SceExtspReadDumpSID("", (PVOID)(List.Name));
  1292. } else {
  1293. DebuggerOut("%ws\n", Name);
  1294. }
  1295. } else {
  1296. DebuggerOut("\n");
  1297. }
  1298. pvAddr = List.Next;
  1299. }
  1300. } else {
  1301. DebuggerOut("\tCan't get address\n");
  1302. }
  1303. } else {
  1304. DebuggerOut("No address specified\n");
  1305. }
  1306. }
  1307. VOID
  1308. DumpSceErrorLogInfo(
  1309. HANDLE hCurrentProcess,
  1310. HANDLE hCurrentThread,
  1311. DWORD dwCurrentPc,
  1312. PNTSD_EXTENSION_APIS lpExtensionApis,
  1313. LPSTR lpArgumentString
  1314. )
  1315. /*++
  1316. Routine Description:
  1317. Dump SCE_ERROR_LOG_INFO structure.
  1318. Arguments:
  1319. hCurrentProcess - Handle for the process being debugged.
  1320. hCurrentThread - Handle for the thread that has the debugger focus.
  1321. dwCurrentPc - Current Program Counter?
  1322. lpExtensionApis - Pointer to a structure that contains pointers to
  1323. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  1324. typedef struct _NTSD_EXTENSION_APIS {
  1325. DWORD nSize;
  1326. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  1327. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  1328. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  1329. PNTSD_DISASM lpDisasmRoutine;
  1330. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1331. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  1332. lpArgumentString - This is a pointer to a string that contains
  1333. space seperated arguments that are passed to debugger
  1334. extension function.
  1335. Return Value:
  1336. none
  1337. --*/
  1338. {
  1339. PVOID pvAddr;
  1340. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  1341. if (lpArgumentString && *lpArgumentString != '\0' )
  1342. {
  1343. pvAddr = (PVOID)(lpGetExpressionRoutine)(lpArgumentString);
  1344. if ( pvAddr ) {
  1345. DebuggerOut("Error log info @%p\n", pvAddr);
  1346. SCE_ERROR_LOG_INFO Info;
  1347. WCHAR Name[1024];
  1348. while ( pvAddr != NULL ) {
  1349. memset(&Info, '\0', sizeof(SCE_ERROR_LOG_INFO));
  1350. GET_DATA(pvAddr, (LPVOID)&Info, sizeof(SCE_ERROR_LOG_INFO));
  1351. DebuggerOut("\t(@%p, Next @%p) Error code %d, ", pvAddr, Info.next, Info.rc);
  1352. Name[0] = L'\0';
  1353. if ( Info.buffer != NULL ) {
  1354. GET_STRING(Info.buffer, Name, 1024);
  1355. DebuggerOut("%ws\n", Name);
  1356. } else {
  1357. DebuggerOut("\n");
  1358. }
  1359. pvAddr = Info.next;
  1360. }
  1361. } else {
  1362. DebuggerOut("\tCan't get address\n");
  1363. }
  1364. } else {
  1365. DebuggerOut("No address specified\n");
  1366. }
  1367. }
  1368. VOID
  1369. DumpScePrivilegeAssignment(
  1370. HANDLE hCurrentProcess,
  1371. HANDLE hCurrentThread,
  1372. DWORD dwCurrentPc,
  1373. PNTSD_EXTENSION_APIS lpExtensionApis,
  1374. LPSTR lpArgumentString
  1375. )
  1376. /*++
  1377. Routine Description:
  1378. Dump SCE_PRIVILEGE_ASSIGNMENT structure.
  1379. Arguments:
  1380. hCurrentProcess - Handle for the process being debugged.
  1381. hCurrentThread - Handle for the thread that has the debugger focus.
  1382. dwCurrentPc - Current Program Counter?
  1383. lpExtensionApis - Pointer to a structure that contains pointers to
  1384. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  1385. typedef struct _NTSD_EXTENSION_APIS {
  1386. DWORD nSize;
  1387. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  1388. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  1389. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  1390. PNTSD_DISASM lpDisasmRoutine;
  1391. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1392. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  1393. lpArgumentString - This is a pointer to a string that contains
  1394. space seperated arguments that are passed to debugger
  1395. extension function.
  1396. Return Value:
  1397. none
  1398. --*/
  1399. {
  1400. PVOID pvAddr;
  1401. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  1402. if (lpArgumentString && *lpArgumentString != '\0' )
  1403. {
  1404. pvAddr = (PVOID)(lpGetExpressionRoutine)(lpArgumentString);
  1405. if ( pvAddr ) {
  1406. DebuggerOut("Privilege assignments @%p\n", pvAddr);
  1407. SCE_PRIVILEGE_ASSIGNMENT Priv;
  1408. WCHAR Name[MAX_PATH];
  1409. while ( pvAddr != NULL ) {
  1410. memset(&Priv, '\0', sizeof(SCE_PRIVILEGE_ASSIGNMENT));
  1411. GET_DATA(pvAddr, (LPVOID)&Priv, sizeof(SCE_PRIVILEGE_ASSIGNMENT));
  1412. DebuggerOut("\t(@%p, Next @%p)", pvAddr, Priv.Next);
  1413. Name[0] = L'\0';
  1414. if ( Priv.Name != NULL ) {
  1415. GET_STRING(Priv.Name, Name, MAX_PATH);
  1416. DebuggerOut("\t%ws", Name);
  1417. } else {
  1418. DebuggerOut("\t<NULL>");
  1419. }
  1420. DebuggerOut(", Value: %d, Status %d\n", Priv.Value, Priv.Status);
  1421. if ( Priv.AssignedTo ) {
  1422. DebuggerOut("\t Assigned To:\n");
  1423. SceExtspReadDumpNameList(Priv.AssignedTo, "\t\t");
  1424. } else {
  1425. DebuggerOut("\t Assigned to no one\n");
  1426. }
  1427. pvAddr = Priv.Next;
  1428. }
  1429. } else {
  1430. DebuggerOut("\tCan't get address\n");
  1431. }
  1432. } else {
  1433. DebuggerOut("No address specified\n");
  1434. }
  1435. }
  1436. VOID
  1437. DumpSceServices(
  1438. HANDLE hCurrentProcess,
  1439. HANDLE hCurrentThread,
  1440. DWORD dwCurrentPc,
  1441. PNTSD_EXTENSION_APIS lpExtensionApis,
  1442. LPSTR lpArgumentString
  1443. )
  1444. /*++
  1445. Routine Description:
  1446. Dump SCE_SERVICES structure.
  1447. Arguments:
  1448. hCurrentProcess - Handle for the process being debugged.
  1449. hCurrentThread - Handle for the thread that has the debugger focus.
  1450. dwCurrentPc - Current Program Counter?
  1451. lpExtensionApis - Pointer to a structure that contains pointers to
  1452. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  1453. typedef struct _NTSD_EXTENSION_APIS {
  1454. DWORD nSize;
  1455. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  1456. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  1457. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  1458. PNTSD_DISASM lpDisasmRoutine;
  1459. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1460. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  1461. lpArgumentString - This is a pointer to a string that contains
  1462. space seperated arguments that are passed to debugger
  1463. extension function.
  1464. Return Value:
  1465. none
  1466. --*/
  1467. {
  1468. PVOID pvAddr;
  1469. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  1470. if (lpArgumentString && *lpArgumentString != '\0' )
  1471. {
  1472. pvAddr = (PVOID)(lpGetExpressionRoutine)(lpArgumentString);
  1473. if ( pvAddr ) {
  1474. DebuggerOut("Services defined @%p\n", pvAddr);
  1475. SCE_SERVICES Serv;
  1476. WCHAR Name[1024];
  1477. while ( pvAddr != NULL ) {
  1478. memset(&Serv, '\0', sizeof(SCE_SERVICES));
  1479. GET_DATA(pvAddr, (LPVOID)&Serv, sizeof(SCE_SERVICES));
  1480. DebuggerOut("\t(@%p, Next @%p) Status %d, Startup %d, SeInfo %d\n",
  1481. pvAddr, Serv.Next, Serv.Status, Serv.Startup, Serv.SeInfo);
  1482. Name[0] = L'\0';
  1483. if ( Serv.ServiceName != NULL ) {
  1484. GET_STRING(Serv.ServiceName, Name, 1024);
  1485. DebuggerOut("\t %ws", Name);
  1486. } else {
  1487. DebuggerOut("\t <No Name>");
  1488. }
  1489. Name[0] = L'\0';
  1490. if ( Serv.DisplayName != NULL ) {
  1491. GET_STRING(Serv.DisplayName, Name, 1024);
  1492. DebuggerOut("\t%ws\n", Name);
  1493. } else {
  1494. DebuggerOut("\t<No Display Name>\n");
  1495. }
  1496. //
  1497. // Dump security descriptor or engine name
  1498. //
  1499. if ( Serv.General.pSecurityDescriptor != NULL ) {
  1500. if ( Serv.SeInfo > 0 ) {
  1501. DebuggerOut("\t Security Descriptor:\n");
  1502. SceExtspReadDumpSD(Serv.SeInfo, Serv.General.pSecurityDescriptor, "\t\t");
  1503. } else {
  1504. //
  1505. // this could be the engine name
  1506. //
  1507. DebuggerOut("\t Service engine name: ");
  1508. Name[0] = L'\0';
  1509. GET_STRING(Serv.General.ServiceEngineName, Name, 1024);
  1510. DebuggerOut("%ws\n", Name);
  1511. }
  1512. }
  1513. pvAddr = Serv.Next;
  1514. }
  1515. } else {
  1516. DebuggerOut("\tCan't get address\n");
  1517. }
  1518. } else {
  1519. DebuggerOut("No address specified\n");
  1520. }
  1521. }
  1522. VOID
  1523. DumpSceGroupMembership(
  1524. HANDLE hCurrentProcess,
  1525. HANDLE hCurrentThread,
  1526. DWORD dwCurrentPc,
  1527. PNTSD_EXTENSION_APIS lpExtensionApis,
  1528. LPSTR lpArgumentString
  1529. )
  1530. /*++
  1531. Routine Description:
  1532. Dump SCE_GROUP_MEMBERSHIP structure.
  1533. Arguments:
  1534. hCurrentProcess - Handle for the process being debugged.
  1535. hCurrentThread - Handle for the thread that has the debugger focus.
  1536. dwCurrentPc - Current Program Counter?
  1537. lpExtensionApis - Pointer to a structure that contains pointers to
  1538. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  1539. typedef struct _NTSD_EXTENSION_APIS {
  1540. DWORD nSize;
  1541. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  1542. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  1543. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  1544. PNTSD_DISASM lpDisasmRoutine;
  1545. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1546. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  1547. lpArgumentString - This is a pointer to a string that contains
  1548. space seperated arguments that are passed to debugger
  1549. extension function.
  1550. Return Value:
  1551. none
  1552. --*/
  1553. {
  1554. PVOID pvAddr;
  1555. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  1556. if (lpArgumentString && *lpArgumentString != '\0' )
  1557. {
  1558. pvAddr = (PVOID)(lpGetExpressionRoutine)(lpArgumentString);
  1559. if ( pvAddr ) {
  1560. DebuggerOut("Group membership defined @%p\n", pvAddr);
  1561. SCE_GROUP_MEMBERSHIP grp;
  1562. WCHAR Name[1024];
  1563. while ( pvAddr != NULL ) {
  1564. memset(&grp, '\0', sizeof(SCE_GROUP_MEMBERSHIP));
  1565. GET_DATA(pvAddr, (LPVOID)&grp, sizeof(SCE_GROUP_MEMBERSHIP));
  1566. DebuggerOut("\t(@%p, Next @%p)", pvAddr, grp.Next);
  1567. Name[0] = L'\0';
  1568. if ( grp.GroupName != NULL ) {
  1569. GET_STRING(grp.GroupName, Name, 1024);
  1570. DebuggerOut("\t%ws\tStatus %d\n", Name, grp.Status);
  1571. } else {
  1572. DebuggerOut("\t<No Group Name>\tStatus %d\n", grp.Status);
  1573. }
  1574. //
  1575. // members
  1576. //
  1577. if ( grp.pMembers ) {
  1578. DebuggerOut("\t Members:\n");
  1579. SceExtspReadDumpNameList(grp.pMembers, "\t\t");
  1580. } else if ( grp.Status & SCE_GROUP_STATUS_NC_MEMBERS ) {
  1581. DebuggerOut("\t Members not defined\n");
  1582. } else {
  1583. DebuggerOut("\t No members\n");
  1584. }
  1585. //
  1586. // memberof
  1587. //
  1588. if ( grp.pMemberOf ) {
  1589. DebuggerOut("\t MemberOf:\n");
  1590. SceExtspReadDumpNameList(grp.pMemberOf, "\t\t");
  1591. } else {
  1592. DebuggerOut("\t MemberOf not defined\n");
  1593. }
  1594. pvAddr = grp.Next;
  1595. }
  1596. } else {
  1597. DebuggerOut("\tCan't get address\n");
  1598. }
  1599. } else {
  1600. DebuggerOut("No address specified\n");
  1601. }
  1602. }
  1603. VOID
  1604. DumpSceObjectSecurity(
  1605. HANDLE hCurrentProcess,
  1606. HANDLE hCurrentThread,
  1607. DWORD dwCurrentPc,
  1608. PNTSD_EXTENSION_APIS lpExtensionApis,
  1609. LPSTR lpArgumentString
  1610. )
  1611. /*++
  1612. Routine Description:
  1613. Dump SCE_OBJECT_SECURITY structure.
  1614. Arguments:
  1615. hCurrentProcess - Handle for the process being debugged.
  1616. hCurrentThread - Handle for the thread that has the debugger focus.
  1617. dwCurrentPc - Current Program Counter?
  1618. lpExtensionApis - Pointer to a structure that contains pointers to
  1619. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  1620. typedef struct _NTSD_EXTENSION_APIS {
  1621. DWORD nSize;
  1622. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  1623. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  1624. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  1625. PNTSD_DISASM lpDisasmRoutine;
  1626. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1627. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  1628. lpArgumentString - This is a pointer to a string that contains
  1629. space seperated arguments that are passed to debugger
  1630. extension function.
  1631. Return Value:
  1632. none
  1633. --*/
  1634. {
  1635. PVOID pvAddr;
  1636. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  1637. if (lpArgumentString && *lpArgumentString != '\0' )
  1638. {
  1639. pvAddr = (PVOID)(lpGetExpressionRoutine)(lpArgumentString);
  1640. if ( pvAddr ) {
  1641. DebuggerOut("Object security @%p\n", pvAddr);
  1642. SceExtspReadDumpObjectSecurity(pvAddr, " ");
  1643. } else {
  1644. DebuggerOut("\tCan't get address\n");
  1645. }
  1646. } else {
  1647. DebuggerOut("No address specified\n");
  1648. }
  1649. }
  1650. VOID
  1651. DumpSceObjectList(
  1652. HANDLE hCurrentProcess,
  1653. HANDLE hCurrentThread,
  1654. DWORD dwCurrentPc,
  1655. PNTSD_EXTENSION_APIS lpExtensionApis,
  1656. LPSTR lpArgumentString
  1657. )
  1658. /*++
  1659. Routine Description:
  1660. Dump SCE_OBJECT_LIST structure.
  1661. Arguments:
  1662. hCurrentProcess - Handle for the process being debugged.
  1663. hCurrentThread - Handle for the thread that has the debugger focus.
  1664. dwCurrentPc - Current Program Counter?
  1665. lpExtensionApis - Pointer to a structure that contains pointers to
  1666. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  1667. typedef struct _NTSD_EXTENSION_APIS {
  1668. DWORD nSize;
  1669. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  1670. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  1671. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  1672. PNTSD_DISASM lpDisasmRoutine;
  1673. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1674. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  1675. lpArgumentString - This is a pointer to a string that contains
  1676. space seperated arguments that are passed to debugger
  1677. extension function.
  1678. Return Value:
  1679. none
  1680. --*/
  1681. {
  1682. PVOID pvAddr;
  1683. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  1684. if (lpArgumentString && *lpArgumentString != '\0' )
  1685. {
  1686. pvAddr = (PVOID)(lpGetExpressionRoutine)(lpArgumentString);
  1687. if ( pvAddr ) {
  1688. DebuggerOut("Object list @%p\n", pvAddr);
  1689. SCE_OBJECT_LIST list;
  1690. WCHAR Name[1024];
  1691. while ( pvAddr != NULL ) {
  1692. memset(&list, '\0', sizeof(SCE_OBJECT_LIST));
  1693. GET_DATA(pvAddr, (LPVOID)&list, sizeof(SCE_OBJECT_LIST));
  1694. DebuggerOut("\t(@%p, Next @%p) Status %d, ", pvAddr, list.Next, list.Status);
  1695. if ( list.IsContainer )
  1696. DebuggerOut("Container,");
  1697. else
  1698. DebuggerOut("NonContainer,");
  1699. DebuggerOut(" Count of children %d\n", list.Count);
  1700. Name[0] = L'\0';
  1701. if ( list.Name != NULL ) {
  1702. GET_STRING(list.Name, Name, 1024);
  1703. DebuggerOut("\t %ws\n", Name);
  1704. } else {
  1705. DebuggerOut("\t <NULL Name>\n");
  1706. }
  1707. pvAddr = list.Next;
  1708. }
  1709. } else {
  1710. DebuggerOut("\tCan't get address\n");
  1711. }
  1712. } else {
  1713. DebuggerOut("No address specified\n");
  1714. }
  1715. }
  1716. VOID
  1717. DumpSceObjectArray(
  1718. HANDLE hCurrentProcess,
  1719. HANDLE hCurrentThread,
  1720. DWORD dwCurrentPc,
  1721. PNTSD_EXTENSION_APIS lpExtensionApis,
  1722. LPSTR lpArgumentString
  1723. )
  1724. /*++
  1725. Routine Description:
  1726. Dump SCE_OBJECT_ARRAY structure.
  1727. Arguments:
  1728. hCurrentProcess - Handle for the process being debugged.
  1729. hCurrentThread - Handle for the thread that has the debugger focus.
  1730. dwCurrentPc - Current Program Counter?
  1731. lpExtensionApis - Pointer to a structure that contains pointers to
  1732. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  1733. typedef struct _NTSD_EXTENSION_APIS {
  1734. DWORD nSize;
  1735. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  1736. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  1737. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  1738. PNTSD_DISASM lpDisasmRoutine;
  1739. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1740. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  1741. lpArgumentString - This is a pointer to a string that contains
  1742. space seperated arguments that are passed to debugger
  1743. extension function.
  1744. Return Value:
  1745. none
  1746. --*/
  1747. {
  1748. PVOID pvAddr;
  1749. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  1750. if (lpArgumentString && *lpArgumentString != '\0' )
  1751. {
  1752. LPSTR szCommand=lpArgumentString;
  1753. LPSTR ThisArg,szValue;
  1754. DWORD Len;
  1755. DWORD StartIndex=0;
  1756. DWORD Count=0;
  1757. LPSTR pszAddr=NULL;
  1758. SceExtspGetNextArgument(&szCommand, &ThisArg, &Len);
  1759. if ( ThisArg && Len > 0 ) {
  1760. do {
  1761. if ( *ThisArg != '-' ) {
  1762. //
  1763. // this is the address
  1764. //
  1765. if ( pszAddr == NULL )
  1766. pszAddr = ThisArg;
  1767. else {
  1768. DebuggerOut("duplicate addr %s\n", ThisArg);
  1769. return;
  1770. }
  1771. } else if ( Len == 2 &&
  1772. ( *(ThisArg+1) == 's' ||
  1773. *(ThisArg+1) == 'c' ) ) {
  1774. //
  1775. // this is the start and end
  1776. //
  1777. SceExtspGetNextArgument(&szCommand, &szValue, &Len);
  1778. if ( szValue && Len > 0 ) {
  1779. if ( *(ThisArg+1) == 's' )
  1780. StartIndex = atoi(szValue);
  1781. else
  1782. Count = atoi(szValue);
  1783. } else {
  1784. DebuggerOut("Invalid arguments\n");
  1785. return;
  1786. }
  1787. } else {
  1788. DebuggerOut("Invalid options\n");
  1789. return;
  1790. }
  1791. SceExtspGetNextArgument(&szCommand, &ThisArg, &Len);
  1792. if ( ThisArg == NULL ) {
  1793. break;
  1794. }
  1795. } while ( *szCommand != '\0' || ThisArg != NULL );
  1796. } else {
  1797. DebuggerOut("No argument\n");
  1798. return;
  1799. }
  1800. if ( pszAddr == NULL ) {
  1801. DebuggerOut("No address specified.\n");
  1802. } else {
  1803. pvAddr = (PVOID)(lpGetExpressionRoutine)(pszAddr);
  1804. if ( pvAddr ) {
  1805. DebuggerOut("Object Array @%p, Start at index %d for %d nodes\n", pvAddr, StartIndex, Count);
  1806. SCE_OBJECT_ARRAY Info;
  1807. memset(&Info, '\0', sizeof(SCE_OBJECT_ARRAY));
  1808. GET_DATA(pvAddr, (LPVOID)&Info, sizeof(SCE_OBJECT_ARRAY));
  1809. DebuggerOut(" Array count %d\tArray pointer @%p\n\n", Info.Count, Info.pObjectArray);
  1810. if ( Info.Count > 0 && Info.pObjectArray &&
  1811. StartIndex < Info.Count ) {
  1812. if ( Count == 0 ) Count = Info.Count;
  1813. if ( Count > (Info.Count - StartIndex) ) {
  1814. Count = Info.Count - StartIndex;
  1815. }
  1816. PVOID *pArray = (PVOID *)LocalAlloc(LPTR, Info.Count*sizeof(PVOID));
  1817. if ( pArray ) {
  1818. GET_DATA((PVOID)(Info.pObjectArray), pArray, Info.Count*sizeof(PVOID));
  1819. for ( DWORD i=StartIndex; i<StartIndex+Count; i++ ) {
  1820. DebuggerOut("Index %d: ", i);
  1821. if ( pArray[i] == NULL ) {
  1822. DebuggerOut("<NULL>\n");
  1823. break;
  1824. } else {
  1825. SceExtspReadDumpObjectSecurity(pArray[i], "\t");
  1826. }
  1827. }
  1828. LocalFree(pArray);
  1829. } else {
  1830. DebuggerOut("\t not enough memory to allocate the array\n");
  1831. }
  1832. }
  1833. } else {
  1834. DebuggerOut("\tCan't get address\n");
  1835. }
  1836. }
  1837. } else {
  1838. DebuggerOut("No address specified\n");
  1839. }
  1840. }
  1841. VOID
  1842. DumpSceRegistryValues(
  1843. HANDLE hCurrentProcess,
  1844. HANDLE hCurrentThread,
  1845. DWORD dwCurrentPc,
  1846. PNTSD_EXTENSION_APIS lpExtensionApis,
  1847. LPSTR lpArgumentString
  1848. )
  1849. /*++
  1850. Routine Description:
  1851. Dump SCE_REGISTRY_VALUE_INFO structure.
  1852. Arguments:
  1853. hCurrentProcess - Handle for the process being debugged.
  1854. hCurrentThread - Handle for the thread that has the debugger focus.
  1855. dwCurrentPc - Current Program Counter?
  1856. lpExtensionApis - Pointer to a structure that contains pointers to
  1857. various routines. (see \nt\public\sdk\inc\ntsdexts.h)
  1858. typedef struct _NTSD_EXTENSION_APIS {
  1859. DWORD nSize;
  1860. PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
  1861. PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
  1862. PNTSD_GET_SYMBOL lpGetSymbolRoutine;
  1863. PNTSD_DISASM lpDisasmRoutine;
  1864. PNTSD_CHECK_CONTROL_C lpCheckControlCRoutine;
  1865. } NTSD_EXTENSION_APIS, *PNTSD_EXTENSION_APIS;
  1866. lpArgumentString - This is a pointer to a string that contains
  1867. space seperated arguments that are passed to debugger
  1868. extension function.
  1869. Return Value:
  1870. none
  1871. --*/
  1872. {
  1873. PVOID pvAddr;
  1874. InitFunctionPointers(hCurrentProcess, lpExtensionApis);
  1875. if (lpArgumentString && *lpArgumentString != '\0' )
  1876. {
  1877. LPSTR szCommand=lpArgumentString;
  1878. LPSTR ThisArg,szValue;
  1879. DWORD Len;
  1880. DWORD StartCount=0;
  1881. DWORD EndCount=1;
  1882. LPSTR pszAddr=NULL;
  1883. SceExtspGetNextArgument(&szCommand, &ThisArg, &Len);
  1884. if ( ThisArg && Len > 0 ) {
  1885. do {
  1886. if ( *ThisArg != '-' ) {
  1887. //
  1888. // this is the address
  1889. //
  1890. if ( pszAddr == NULL )
  1891. pszAddr = ThisArg;
  1892. else {
  1893. DebuggerOut("duplicate addr %s\n", ThisArg);
  1894. return;
  1895. }
  1896. } else if ( Len == 2 &&
  1897. ( *(ThisArg+1) == 's' ||
  1898. *(ThisArg+1) == 'e' ) ) {
  1899. //
  1900. // this is the start and end
  1901. //
  1902. SceExtspGetNextArgument(&szCommand, &szValue, &Len);
  1903. if ( szValue && Len > 0 ) {
  1904. if ( *(ThisArg+1) == 's' )
  1905. StartCount = atoi(szValue);
  1906. else
  1907. EndCount = atoi(szValue);
  1908. } else {
  1909. DebuggerOut("Invalid arguments\n");
  1910. return;
  1911. }
  1912. } else {
  1913. DebuggerOut("Invalid options\n");
  1914. return;
  1915. }
  1916. SceExtspGetNextArgument(&szCommand, &ThisArg, &Len);
  1917. if ( ThisArg == NULL ) {
  1918. break;
  1919. }
  1920. } while ( *szCommand != '\0' || ThisArg != NULL );
  1921. } else {
  1922. DebuggerOut("No argument\n");
  1923. return;
  1924. }
  1925. if ( pszAddr == NULL ) {
  1926. DebuggerOut("No address specified.\n");
  1927. } else if ( StartCount >= EndCount ) {
  1928. DebuggerOut("Invalid counts.\n");
  1929. } else {
  1930. //
  1931. // get the object tree address
  1932. //
  1933. pvAddr = (PVOID)(lpGetExpressionRoutine)(pszAddr);
  1934. if ( pvAddr ) {
  1935. DebuggerOut("Registry Values @%p, Start %d, End %d\n", pvAddr, StartCount, EndCount);
  1936. SCE_REGISTRY_VALUE_INFO info;
  1937. WCHAR Name[1024];
  1938. pvAddr = (PVOID)( (PBYTE)pvAddr + StartCount*sizeof(SCE_REGISTRY_VALUE_INFO) );
  1939. for (DWORD i=StartCount; i< EndCount; i++) {
  1940. memset(&info, '\0', sizeof(SCE_REGISTRY_VALUE_INFO));
  1941. GET_DATA(pvAddr, (PVOID)&info, sizeof(SCE_REGISTRY_VALUE_INFO));
  1942. Name[0] = L'\0';
  1943. if ( info.FullValueName ) {
  1944. GET_STRING((PWSTR)(info.FullValueName), Name, 1024);
  1945. DebuggerOut("\t%ws,", Name);
  1946. } else {
  1947. DebuggerOut("\t<NULL>,");
  1948. break;
  1949. }
  1950. DebuggerOut(" Status %d, Type %d,", info.Status, info.ValueType);
  1951. Name[0] = L'\0';
  1952. if ( info.Value ) {
  1953. GET_STRING((PWSTR)(info.Value), Name, 1024);
  1954. DebuggerOut(" %ws\n", Name);
  1955. } else {
  1956. DebuggerOut(" <No value>\n");
  1957. }
  1958. pvAddr = (PVOID)( (PBYTE)pvAddr + sizeof(SCE_REGISTRY_VALUE_INFO) );
  1959. }
  1960. } else {
  1961. DebuggerOut("Can't get address of registry value.\n");
  1962. }
  1963. }
  1964. } else {
  1965. DebuggerOut("No argument specified.\n");
  1966. }
  1967. }