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.

763 lines
19 KiB

  1. #include "sceexts.h"
  2. #include <sddl.h>
  3. VOID
  4. SceExtspDumpObjectSubTree(
  5. IN PVOID pvAddr,
  6. IN DWORD cLevel,
  7. IN DWORD mLevel,
  8. IN BOOL bDumpSD
  9. );
  10. VOID
  11. SceExtspReadDumpACL(
  12. IN PVOID pvAcl,
  13. IN SECURITY_INFORMATION SeInfo,
  14. IN LPSTR szPrefix
  15. );
  16. VOID
  17. SceExtspDumpSplayNodes(
  18. IN PVOID pvAddr,
  19. IN PVOID pvSentinel,
  20. IN SCEP_NODE_VALUE_TYPE Type
  21. )
  22. {
  23. if ( pvAddr == NULL ) return;
  24. SCEP_SPLAY_NODE SplayNode;
  25. memset(&SplayNode, '\0', sizeof(SCEP_SPLAY_NODE));
  26. GET_DATA( pvAddr, (LPVOID)&SplayNode, sizeof(SCEP_SPLAY_NODE));
  27. //
  28. // dump left nodes
  29. //
  30. if ( pvAddr != pvSentinel &&
  31. SplayNode.Left != pvSentinel)
  32. SceExtspDumpSplayNodes((PVOID)(SplayNode.Left), pvSentinel, Type);
  33. DebuggerOut("\tAddress @%p, Left @%p, Right @%p\n", pvAddr, SplayNode.Left, SplayNode.Right);
  34. if ( pvAddr != pvSentinel ) {
  35. //
  36. // get the value
  37. //
  38. PVOID pValue = (PVOID)LocalAlloc(LPTR, SplayNode.dwByteLength+2);
  39. if ( pValue ) {
  40. if ( Type == SplayNodeStringType) {
  41. GET_STRING( (PWSTR)(SplayNode.Value), (PWSTR)pValue, SplayNode.dwByteLength+2);
  42. DebuggerOut("\t\tBytes: %d\t%ws\n", SplayNode.dwByteLength, (PWSTR)pValue);
  43. } else if ( Type == SplayNodeSidType ) {
  44. DebuggerOut("\t\tBytes: %d", SplayNode.dwByteLength);
  45. SceExtspReadDumpSID("\t\t",(LPVOID)(SplayNode.Value));
  46. } else {
  47. DebuggerOut("\t\tInvalid splay type %d\n", Type);
  48. }
  49. LocalFree(pValue);
  50. } else {
  51. DebuggerOut("\t\tCan't allocate memory for Value\n");
  52. }
  53. }
  54. //
  55. // dump right nodes
  56. //
  57. if ( pvAddr != pvSentinel &&
  58. SplayNode.Right != pvSentinel )
  59. SceExtspDumpSplayNodes((PVOID)(SplayNode.Right), pvSentinel, Type);
  60. }
  61. VOID
  62. SceExtspDumpQueueNode(
  63. IN PVOID pvAddr,
  64. IN BOOL bOneNode
  65. )
  66. {
  67. if ( pvAddr == NULL ) return;
  68. PVOID pvTemp=pvAddr;
  69. SCESRV_POLQUEUE PolNode;
  70. do {
  71. memset(&PolNode, '\0', sizeof(SCESRV_POLQUEUE));
  72. GET_DATA(pvTemp, (LPVOID)&PolNode, sizeof(SCESRV_POLQUEUE));
  73. DebuggerOut("\tQueue Node @%p, Next Node @%p\n", pvTemp, PolNode.Next);
  74. SceExtspDumpNotificationInfo(PolNode.DbType, PolNode.ObjectType, PolNode.DeltaType);
  75. DebuggerOut("\t Pending %d\tRight %08x%08x\n", PolNode.dwPending, PolNode.ExplicitHighRight, PolNode.ExplicitLowRight);
  76. SceExtspReadDumpSID("\t", PolNode.Sid);
  77. pvTemp = PolNode.Next;
  78. } while ( !bOneNode && pvTemp != NULL);
  79. }
  80. VOID
  81. SceExtspReadDumpSID(
  82. IN LPSTR szPrefix,
  83. IN PVOID pvSid
  84. )
  85. {
  86. if ( pvSid == NULL ) return;
  87. SID Sid;
  88. PSID pSid;
  89. GET_DATA( pvSid, (LPVOID)&Sid, sizeof(SID));
  90. DWORD Len = RtlLengthRequiredSid(Sid.SubAuthorityCount);
  91. pSid = (PSID)LocalAlloc(LPTR, Len);
  92. if (pSid == NULL)
  93. {
  94. DebuggerOut("%sUnable to allocate memory to print SID\n", szPrefix);
  95. }
  96. else
  97. {
  98. GET_DATA( pvSid, (LPVOID)pSid, Len);
  99. UNICODE_STRING ucsSid;
  100. ucsSid.Length = 0;
  101. ucsSid.Buffer = NULL;
  102. RtlConvertSidToUnicodeString(&ucsSid, pSid, TRUE);
  103. CHAR Name[MAX_PATH];
  104. CHAR Dom[MAX_PATH];
  105. DWORD cDom=MAX_PATH;
  106. DWORD cName=MAX_PATH;
  107. SID_NAME_USE Use;
  108. Name[0] = '\0';
  109. Dom[0] = '\0';
  110. LookupAccountSid(NULL, pSid, Name, &cName, Dom, &cDom, &Use);
  111. DebuggerOut("%s%wZ\t%s\\%s\n", szPrefix, &ucsSid, Dom, Name);
  112. RtlFreeUnicodeString(&ucsSid);
  113. LocalFree(pSid);
  114. }
  115. }
  116. VOID
  117. SceExtspDumpNotificationInfo(
  118. IN SECURITY_DB_TYPE DbType,
  119. IN SECURITY_DB_OBJECT_TYPE ObjectType,
  120. IN SECURITY_DB_DELTA_TYPE DeltaType
  121. )
  122. {
  123. switch ( DbType) {
  124. case SecurityDbSam:
  125. DebuggerOut("\t SAM");
  126. break;
  127. case SecurityDbLsa:
  128. DebuggerOut("\t LSA");
  129. break;
  130. default:
  131. DebuggerOut("\t Unknown Db %d", DbType);
  132. }
  133. switch ( ObjectType) {
  134. case SecurityDbObjectSamDomain:
  135. DebuggerOut("\tDomain");
  136. break;
  137. case SecurityDbObjectSamUser:
  138. case SecurityDbObjectSamGroup:
  139. case SecurityDbObjectSamAlias:
  140. DebuggerOut("\tAccount");
  141. break;
  142. case SecurityDbObjectLsaPolicy:
  143. DebuggerOut("\tPolicy");
  144. break;
  145. case SecurityDbObjectLsaAccount:
  146. DebuggerOut("\tRight");
  147. break;
  148. default:
  149. DebuggerOut("\tUnknown Object %d", ObjectType);
  150. }
  151. switch ( DeltaType) {
  152. case SecurityDbNew:
  153. case SecurityDbRename:
  154. case SecurityDbChange:
  155. DebuggerOut("\tChange");
  156. break;
  157. case SecurityDbDelete:
  158. DebuggerOut("\tDelete");
  159. break;
  160. default:
  161. DebuggerOut("\tUnknown Delta %d", DeltaType);
  162. }
  163. }
  164. VOID
  165. SceExtspDumpADLNodes(
  166. IN PVOID pvAddr
  167. )
  168. {
  169. if ( pvAddr == NULL ) return;
  170. PVOID pvAddr2 = pvAddr;
  171. SCEP_ADL_NODE AdlNode;
  172. while ( pvAddr2 != NULL ) {
  173. memset(&AdlNode, '\0', sizeof(SCEP_ADL_NODE));
  174. GET_DATA(pvAddr, (LPVOID)&AdlNode, sizeof(SCEP_ADL_NODE));
  175. DebuggerOut("\tThis Node @%p, Next @%p\n", pvAddr, AdlNode.Next);
  176. if ( AdlNode.pSid == NULL ) {
  177. DebuggerOut("\t Null Sid\n");
  178. break;
  179. } else {
  180. SceExtspReadDumpSID("\t ", AdlNode.pSid);
  181. }
  182. DebuggerOut("\t AceType %d\tMask %x\n", AdlNode.AceType, AdlNode.dwEffectiveMask);
  183. DebuggerOut("\t CIIO %x\tOIIO %x\tNICIIO %x\n", AdlNode.dw_CI_IO_Mask,
  184. AdlNode.dw_OI_IO_Mask, AdlNode.dw_NP_CI_IO_Mask);
  185. //
  186. // look for GUIDs
  187. //
  188. GUID guid;
  189. if ( AdlNode.pGuidObjectType != NULL ) {
  190. memset(&guid, '\0', sizeof(GUID));
  191. GET_DATA( (LPVOID)(AdlNode.pGuidObjectType), (LPVOID)&guid, sizeof(GUID));
  192. DebuggerOut("\t Object Type GUID");
  193. SceExtspDumpGUID( (GUID *)&guid);
  194. } else {
  195. DebuggerOut("\t Null Object Type GUID\n");
  196. }
  197. if ( AdlNode.pGuidInheritedObjectType != NULL ) {
  198. memset(&guid, '\0', sizeof(GUID));
  199. GET_DATA( (LPVOID)(AdlNode.pGuidInheritedObjectType), (LPVOID)&guid, sizeof(GUID));
  200. DebuggerOut("\t Inherited Object Type GUID");
  201. SceExtspDumpGUID( (GUID *)&guid);
  202. } else {
  203. DebuggerOut("\t Null Inherited Object Type GUID\n");
  204. }
  205. pvAddr2 = AdlNode.Next;
  206. }
  207. }
  208. VOID
  209. SceExtspDumpGUID(
  210. IN GUID *pGUID
  211. )
  212. {
  213. if ( pGUID == NULL ) return;
  214. DebuggerOut("{%08x-%04x-%04x-%s}\n",pGUID->Data1, pGUID->Data2,
  215. pGUID->Data3, pGUID->Data4);
  216. }
  217. VOID
  218. SceExtspGetNextArgument(
  219. IN OUT LPSTR *pszCommand,
  220. OUT LPSTR *pArg,
  221. OUT DWORD *pLen
  222. )
  223. {
  224. if ( pszCommand == NULL || pArg == NULL || pLen == NULL ) return;
  225. LPSTR pTemp=*pszCommand;
  226. *pArg = NULL;
  227. *pLen = 0;
  228. while ( *pTemp == ' ') pTemp++;
  229. if ( *pTemp == '\0' ) return;
  230. //
  231. // this is the start of this argument
  232. //
  233. *pArg = pTemp;
  234. while ( *pTemp != ' ' && *pTemp != '\0' ) pTemp++;
  235. *pLen = (DWORD)(pTemp - (*pArg));
  236. *pszCommand = pTemp;
  237. }
  238. VOID
  239. SceExtspDumpObjectTree(
  240. IN PVOID pvAddr,
  241. IN DWORD Level,
  242. IN DWORD Count,
  243. IN PWSTR wszName,
  244. IN BOOL bDumpSD
  245. )
  246. {
  247. if ( pvAddr == NULL ) return;
  248. SCE_OBJECT_TREE tree;
  249. memset(&tree, '\0', sizeof(SCE_OBJECT_TREE));
  250. GET_DATA(pvAddr, (PVOID)&tree, sizeof(SCE_OBJECT_TREE));
  251. DebuggerOut("\n Root Node @%p\n", pvAddr);
  252. WCHAR FullName[1024];
  253. FullName[0] = L'\0';
  254. GET_STRING( tree.ObjectFullName, FullName, 1024 );
  255. DebuggerOut("\n Root Node '%ws', (Container %d, Status %d, Count %d)\n",
  256. FullName, tree.IsContainer, tree.Status, tree.dwSize_aChildNames);
  257. if ( bDumpSD ) {
  258. DebuggerOut(" Security Descriptor:\n");
  259. SceExtspReadDumpSD(tree.SeInfo, tree.pSecurityDescriptor, "\t ");
  260. DebuggerOut(" Merged Security Descriptor:\n");
  261. SceExtspReadDumpSD(tree.SeInfo, tree.pApplySecurityDescriptor, "\t ");
  262. }
  263. if ( tree.ChildList ) {
  264. DebuggerOut(" Child List @%p:\n", tree.ChildList);
  265. //
  266. // get child object list
  267. //
  268. SCE_OBJECT_CHILD_LIST list;
  269. PVOID pvTemp = (PVOID)(tree.ChildList);
  270. DWORD LocalCount = 0;
  271. if ( wszName[0] != L'\0' ) {
  272. //
  273. // find the child object name to start with
  274. //
  275. WCHAR NodeName[MAX_PATH];
  276. do {
  277. memset(&list, '\0', sizeof(SCE_OBJECT_CHILD_LIST));
  278. GET_DATA( pvTemp, (PVOID)&list, sizeof(SCE_OBJECT_CHILD_LIST));
  279. if ( list.Node ) {
  280. PWSTR pszName=NULL;
  281. GET_DATA((PVOID)(list.Node), (PVOID)&pszName, sizeof(PWSTR));
  282. if ( pszName ) {
  283. NodeName[0] = L'\0';
  284. GET_STRING(pszName, NodeName, MAX_PATH);
  285. if ( _wcsicmp(NodeName, wszName) >= 0 )
  286. break;
  287. }
  288. } else {
  289. DebuggerOut("\tNode in @%p is null\n", pvTemp);
  290. }
  291. pvTemp = list.Next;
  292. } while ( pvTemp != NULL );
  293. if ( pvTemp == NULL ) {
  294. //
  295. // didn't find the name to start with
  296. //
  297. DebuggerOut("\tCannot find a child name greater than %ws\n", wszName);
  298. return;
  299. }
  300. }
  301. //
  302. // now continue to dump all children
  303. //
  304. do {
  305. memset(&list, '\0', sizeof(SCE_OBJECT_CHILD_LIST));
  306. GET_DATA( pvTemp, (PVOID)&list, sizeof(SCE_OBJECT_CHILD_LIST));
  307. if ( list.Node ) {
  308. LocalCount++;
  309. SceExtspDumpObjectSubTree((PVOID)(list.Node), 1, Level, bDumpSD);
  310. } else {
  311. DebuggerOut("\tNode in @%p is null\n", pvTemp);
  312. }
  313. pvTemp = list.Next;
  314. } while ( pvTemp != NULL && (Count == 0 || LocalCount <= Count) );
  315. } else {
  316. DebuggerOut("\tNo child list\n");
  317. }
  318. }
  319. VOID
  320. SceExtspDumpObjectSubTree(
  321. IN PVOID pvAddr,
  322. IN DWORD cLevel,
  323. IN DWORD mLevel,
  324. IN BOOL bDumpSD
  325. )
  326. {
  327. if ( pvAddr == NULL ) return;
  328. DebuggerOut("\n");
  329. LPSTR szPrefix = (LPSTR)LocalAlloc( LPTR, cLevel+3);
  330. DWORD i;
  331. if ( szPrefix == NULL ) {
  332. for (i=0; i<cLevel; i++ ) {
  333. DebuggerOut("\t");
  334. }
  335. DebuggerOut("Out of memory to allocate prefix\n");
  336. return;
  337. }
  338. SCE_OBJECT_TREE tree;
  339. memset(&tree, '\0', sizeof(SCE_OBJECT_TREE));
  340. GET_DATA(pvAddr, (PVOID)&tree, sizeof(SCE_OBJECT_TREE));
  341. for (i=0; i<cLevel;i++ ) {
  342. strcat(szPrefix, "\t");
  343. }
  344. WCHAR Name[MAX_PATH];
  345. Name[0] = L'\0';
  346. GET_STRING(tree.Name, Name, MAX_PATH);
  347. DebuggerOut("%sNode @%p: '%ws', (Container %d, Status %d, Count %d)\n",
  348. szPrefix, pvAddr, Name, tree.IsContainer, tree.Status, tree.dwSize_aChildNames);
  349. if ( bDumpSD ) {
  350. DebuggerOut("%s Security Descriptor:\n", szPrefix);
  351. strcat(szPrefix, " ");
  352. SceExtspReadDumpSD(tree.SeInfo, tree.pSecurityDescriptor, szPrefix);
  353. szPrefix[cLevel] = '\0';
  354. DebuggerOut("%s Merged Security Descriptor:\n", szPrefix);
  355. szPrefix[cLevel] = ' ';
  356. SceExtspReadDumpSD(tree.SeInfo, tree.pApplySecurityDescriptor, szPrefix);
  357. szPrefix[cLevel] = '\0';
  358. }
  359. if ( tree.ChildList ) {
  360. if ( mLevel == 0 || cLevel < mLevel ) {
  361. DebuggerOut("%s Child List @%p:\n", szPrefix, tree.ChildList);
  362. //
  363. // get child object list
  364. //
  365. SCE_OBJECT_CHILD_LIST list;
  366. PVOID pvTemp = (PVOID)(tree.ChildList);
  367. //
  368. // now continue to dump all children
  369. //
  370. do {
  371. memset(&list, '\0', sizeof(SCE_OBJECT_CHILD_LIST));
  372. GET_DATA( pvTemp, (PVOID)&list, sizeof(SCE_OBJECT_CHILD_LIST));
  373. if ( list.Node ) {
  374. SceExtspDumpObjectSubTree((PVOID)(list.Node), cLevel+1, mLevel, bDumpSD);
  375. } else {
  376. DebuggerOut("%sNode in @%p is null\n", szPrefix, pvTemp);
  377. }
  378. pvTemp = list.Next;
  379. } while ( pvTemp != NULL );
  380. }
  381. } else {
  382. DebuggerOut("%sNo childrn\n", szPrefix);
  383. }
  384. LocalFree(szPrefix);
  385. }
  386. VOID
  387. SceExtspReadDumpSD(
  388. IN SECURITY_INFORMATION SeInfo,
  389. IN PVOID pvSD,
  390. IN LPSTR szPrefix
  391. )
  392. {
  393. if ( pvSD == NULL || SeInfo == 0 ) {
  394. DebuggerOut("%sNULL SD\n", szPrefix);
  395. return;
  396. }
  397. SECURITY_DESCRIPTOR SD;
  398. PSID Owner = NULL, Group = NULL;
  399. PACL Dacl = NULL, Sacl = NULL;
  400. GET_DATA( pvSD, &SD, sizeof( SECURITY_DESCRIPTOR ) );
  401. DebuggerOut( "%sRevision %d, Sbz1 %d, Control 0x%lx\n",
  402. szPrefix, SD.Revision, SD.Sbz1, SD.Control );
  403. if ( ( SD.Control & SE_SELF_RELATIVE ) == SE_SELF_RELATIVE ) {
  404. if ( SD.Owner != 0 &&
  405. (SeInfo & OWNER_SECURITY_INFORMATION))
  406. Owner = ( PSID )( ( PUCHAR )pvSD + ( ULONG_PTR )SD.Owner );
  407. if ( SD.Group != 0 &&
  408. (SeInfo & GROUP_SECURITY_INFORMATION) )
  409. Group = ( PSID )( ( PUCHAR )pvSD + ( ULONG_PTR )SD.Group );
  410. if ( SD.Dacl != 0 &&
  411. (SeInfo & DACL_SECURITY_INFORMATION) )
  412. Dacl = ( PACL )( ( PUCHAR )pvSD + ( ULONG_PTR )SD.Dacl );
  413. if ( SD.Sacl != 0 &&
  414. (SeInfo & SACL_SECURITY_INFORMATION) )
  415. Sacl = ( PACL )( ( PUCHAR )pvSD + ( ULONG_PTR )SD.Sacl );
  416. } else {
  417. if ( SeInfo & OWNER_SECURITY_INFORMATION )
  418. Owner = SD.Owner;
  419. if ( SeInfo & GROUP_SECURITY_INFORMATION )
  420. Group = SD.Group;
  421. if ( SeInfo & DACL_SECURITY_INFORMATION )
  422. Dacl = SD.Dacl;
  423. if ( SeInfo & SACL_SECURITY_INFORMATION )
  424. Sacl = SD.Sacl;
  425. }
  426. if ( SeInfo & OWNER_SECURITY_INFORMATION ) {
  427. DebuggerOut( "%sOwner: ", szPrefix);
  428. if ( Owner ) {
  429. SceExtspReadDumpSID( szPrefix, Owner );
  430. } else {
  431. DebuggerOut( "<NULL>\n" );
  432. }
  433. }
  434. if ( SeInfo & GROUP_SECURITY_INFORMATION ) {
  435. DebuggerOut( "%sGroup: ", szPrefix);
  436. if ( Group ) {
  437. SceExtspReadDumpSID( szPrefix, Group );
  438. } else {
  439. DebuggerOut( "<NULL>\n" );
  440. }
  441. }
  442. if ( SeInfo & DACL_SECURITY_INFORMATION ) {
  443. if ( Dacl ) {
  444. SceExtspReadDumpACL(Dacl,
  445. DACL_SECURITY_INFORMATION,
  446. szPrefix
  447. );
  448. } else {
  449. DebuggerOut( "%s<NULL DACL>\n",szPrefix );
  450. }
  451. }
  452. if ( SeInfo & SACL_SECURITY_INFORMATION ) {
  453. if ( Sacl ) {
  454. SceExtspReadDumpACL(Sacl,
  455. SACL_SECURITY_INFORMATION,
  456. szPrefix
  457. );
  458. } else {
  459. DebuggerOut( "%s<NULL SACL>\n", szPrefix );
  460. }
  461. }
  462. DebuggerOut( "\n" );
  463. }
  464. VOID
  465. SceExtspReadDumpACL(
  466. IN PVOID pvAcl,
  467. IN SECURITY_INFORMATION SeInfo,
  468. IN LPSTR szPrefix
  469. )
  470. {
  471. ACL ReadAcl;
  472. PACL pAcl=NULL;
  473. SECURITY_DESCRIPTOR SD;
  474. GET_DATA(pvAcl, (PVOID)&ReadAcl, sizeof(ACL));
  475. if ( ReadAcl.AclSize > 0 ) {
  476. pAcl = (PACL)LocalAlloc(LPTR, ReadAcl.AclSize+1);
  477. if ( pAcl ) {
  478. GET_DATA( pvAcl, (PVOID)pAcl, ReadAcl.AclSize);
  479. InitializeSecurityDescriptor (&SD, SECURITY_DESCRIPTOR_REVISION);
  480. SD.Owner = NULL;
  481. SD.Group = NULL;
  482. SD.Dacl = NULL;
  483. SD.Sacl = NULL;
  484. if ( SeInfo == DACL_SECURITY_INFORMATION ) {
  485. RtlSetDaclSecurityDescriptor (&SD, TRUE, pAcl, FALSE);
  486. } else {
  487. RtlSetSaclSecurityDescriptor (&SD, TRUE, pAcl, FALSE);
  488. }
  489. LPSTR strSD=NULL;
  490. if ( ConvertSecurityDescriptorToStringSecurityDescriptorA(&SD,
  491. SDDL_REVISION,
  492. SeInfo,
  493. &strSD,
  494. NULL
  495. ) ) {
  496. DebuggerOut("%s%s\n", szPrefix, strSD);
  497. LocalFree(strSD);
  498. } else {
  499. DWORD rc = GetLastError();
  500. DebuggerOut("%sError %d to convert security descriptor\n", szPrefix, rc);
  501. }
  502. LocalFree(pAcl);
  503. } else {
  504. DebuggerOut("%sNot enough memory to allocate ACL\n", szPrefix);
  505. }
  506. } else {
  507. DebuggerOut("%sACL size is %d\n", szPrefix, ReadAcl.AclSize);
  508. }
  509. }
  510. VOID
  511. SceExtspReadDumpNameList(
  512. IN PVOID pvAddr,
  513. IN LPSTR szPrefix
  514. )
  515. {
  516. SCE_NAME_LIST List;
  517. WCHAR Name[1024];
  518. while ( pvAddr != NULL ) {
  519. memset(&List, '\0', sizeof(SCE_NAME_LIST));
  520. GET_DATA(pvAddr, (LPVOID)&List, sizeof(SCE_NAME_LIST));
  521. Name[0] = L'\0';
  522. if ( List.Name != NULL )
  523. GET_STRING(List.Name, Name, 1024);
  524. DebuggerOut("%s(@%p, Next @%p) %ws\n", szPrefix, List.Name, List.Next, Name);
  525. pvAddr = List.Next;
  526. }
  527. }
  528. VOID
  529. SceExtspReadDumpObjectSecurity(
  530. IN PVOID pvAddr,
  531. IN LPSTR szPrefix
  532. )
  533. {
  534. SCE_OBJECT_SECURITY obj;
  535. memset(&obj, '\0', sizeof(SCE_OBJECT_SECURITY));
  536. GET_DATA(pvAddr, (PVOID)&obj, sizeof(SCE_OBJECT_SECURITY));
  537. WCHAR FullName[1024];
  538. FullName[0] = L'\0';
  539. GET_STRING( obj.Name, FullName, 1024 );
  540. DebuggerOut("%s%ws,", szPrefix, FullName);
  541. if ( obj.IsContainer )
  542. DebuggerOut("\tContainer");
  543. else
  544. DebuggerOut("\tNonContainer");
  545. DebuggerOut(", Status %d\n", obj.Status);
  546. DebuggerOut("%s\tSecurity Descriptor defined:\n", szPrefix);
  547. CHAR newPrefix[MAX_PATH];
  548. strcpy(newPrefix, szPrefix);
  549. strcat(newPrefix, "\t ");
  550. SceExtspReadDumpSD(obj.SeInfo, obj.pSecurityDescriptor, newPrefix);
  551. }