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.

273 lines
6.4 KiB

  1. //
  2. // NDS Browser Test App
  3. //
  4. // Cory West
  5. //
  6. #include "ndsapi32.h"
  7. #include "nds.h"
  8. VOID
  9. ConsoleDumpSubordinates(
  10. PNDS_RESPONSE_SUBORDINATE_LIST pSubList
  11. );
  12. int
  13. _cdecl main(
  14. int argc,
  15. char **argv
  16. ) {
  17. NTSTATUS Status;
  18. //
  19. // For NwNdsOpenTreeHandle
  20. //
  21. HANDLE hRdr;
  22. OEM_STRING oemStr;
  23. UNICODE_STRING ObjectName;
  24. WCHAR NdsStr[256];
  25. //
  26. // For NwNdsResolveName
  27. //
  28. PNDS_RESPONSE_RESOLVE_NAME psResolveName;
  29. DWORD dwOid;
  30. UNICODE_STRING ReferredServer;
  31. WCHAR ServerName[48];
  32. HANDLE hReferredServer;
  33. DWORD dwHandleType;
  34. //
  35. // For NwNdsReadObjectInfo
  36. //
  37. BYTE RawResponse[1024];
  38. PNDS_RESPONSE_GET_OBJECT_INFO psGetInfo;
  39. PBYTE pbRawGetInfo;
  40. DWORD dwStrLen;
  41. //
  42. // For NwNdsList
  43. //
  44. DWORD dwIterHandle;
  45. /**************************************************/
  46. //
  47. // Examine the argument count and hope for the best.
  48. //
  49. if ( argc != 3 ) {
  50. printf( "Usage: browser <tree name> <ds object path>\n" );
  51. printf( "For example, browser marsdev dev.mars\n");
  52. return -1;
  53. }
  54. //
  55. // Convert the tree name string to unicode.
  56. //
  57. oemStr.Length = strlen( argv[1] );
  58. oemStr.MaximumLength = oemStr.Length;
  59. oemStr.Buffer = argv[1];
  60. ObjectName.Length = 0;
  61. ObjectName.MaximumLength = sizeof( NdsStr );
  62. ObjectName.Buffer = NdsStr;
  63. RtlOemStringToUnicodeString( &ObjectName, &oemStr, FALSE );
  64. //
  65. // Get a handle to the redirector.
  66. //
  67. Status = NwNdsOpenTreeHandle( &ObjectName,
  68. &hRdr );
  69. if ( !NT_SUCCESS( Status ) ) {
  70. printf( "*** Open Handle to Nds Tree: Status = %08lx\n", Status );
  71. return -1;
  72. }
  73. //
  74. // Resolve the name that we have to an object id.
  75. //
  76. oemStr.Length = strlen(argv[2]);
  77. oemStr.MaximumLength = oemStr.Length;
  78. oemStr.Buffer = argv[2];
  79. ObjectName.Length = 0;
  80. ObjectName.MaximumLength = sizeof(NdsStr);
  81. ObjectName.Buffer = NdsStr;
  82. RtlOemStringToUnicodeString( &ObjectName, &oemStr, FALSE );
  83. ReferredServer.Buffer = ServerName;
  84. ReferredServer.MaximumLength = sizeof( ServerName );
  85. ReferredServer.Length = 0;
  86. Status = NwNdsResolveName ( hRdr,
  87. &ObjectName,
  88. &dwOid,
  89. &ReferredServer,
  90. NULL,
  91. 0 );
  92. if ( !NT_SUCCESS( Status ) ) {
  93. printf( "*** Resolve Name: Status = %08lx\n", Status );
  94. goto Exit;
  95. }
  96. if ( ReferredServer.Length != 0 ) {
  97. //
  98. // We have to jump servers.
  99. //
  100. Status = NwNdsOpenGenericHandle( &ReferredServer,
  101. &dwHandleType,
  102. &hReferredServer );
  103. if ( !NT_SUCCESS( Status ) ) {
  104. printf( "*** Couldn't open referred server: Status = %08lx\n", Status );
  105. goto Exit;
  106. }
  107. CloseHandle( hRdr );
  108. hRdr = hReferredServer;
  109. }
  110. printf( "=========================== NDS Object Info ===========================\n" );
  111. printf( "Object ID = 0x%08lx\n", dwOid );
  112. //
  113. // Go for the object information.
  114. //
  115. Status = NwNdsReadObjectInfo( hRdr,
  116. dwOid,
  117. RawResponse,
  118. sizeof( RawResponse ) );
  119. if ( !NT_SUCCESS( Status ) ) {
  120. printf( "*** Get Object Info: Status = %08lx\n", Status );
  121. goto Exit;
  122. }
  123. psGetInfo = ( PNDS_RESPONSE_GET_OBJECT_INFO ) RawResponse;
  124. printf( "Flags = 0x%08lx\n", psGetInfo->EntryFlags );
  125. printf( "Subordinate Count = 0x%08lx\n", psGetInfo->SubordinateCount );
  126. printf( "Last Modified Time = 0x%08lx\n", psGetInfo->ModificationTime );
  127. //
  128. // Dig out the two unicode strings for class name and object name.
  129. //
  130. pbRawGetInfo = RawResponse;
  131. pbRawGetInfo += sizeof ( NDS_RESPONSE_GET_OBJECT_INFO );
  132. dwStrLen = * ( DWORD * ) pbRawGetInfo;
  133. pbRawGetInfo += sizeof( DWORD );
  134. printf( "Class Name: %S\n", pbRawGetInfo );
  135. pbRawGetInfo += ROUNDUP4( dwStrLen );
  136. dwStrLen = * ( DWORD * ) pbRawGetInfo;
  137. pbRawGetInfo += sizeof( DWORD );
  138. printf( "Object Name: %S\n", pbRawGetInfo );
  139. //
  140. // Get the subordinate list.
  141. //
  142. if ( psGetInfo->SubordinateCount ) {
  143. dwIterHandle = INITIAL_ITERATION;
  144. do {
  145. Status = NwNdsList( hRdr,
  146. dwOid,
  147. &dwIterHandle,
  148. RawResponse,
  149. sizeof( RawResponse ) );
  150. if ( !NT_SUCCESS( Status ) ) {
  151. printf( "*** List Subordinates: Status = %08lx\n", Status );
  152. goto Exit;
  153. }
  154. ConsoleDumpSubordinates( (PNDS_RESPONSE_SUBORDINATE_LIST) RawResponse );
  155. } while ( dwIterHandle != INITIAL_ITERATION );
  156. }
  157. Exit:
  158. CloseHandle( hRdr );
  159. if ( NT_SUCCESS( Status ) ) {
  160. return 0;
  161. } else {
  162. return -1;
  163. }
  164. }
  165. VOID
  166. ConsoleDumpSubordinates(
  167. PNDS_RESPONSE_SUBORDINATE_LIST pSubList
  168. ) {
  169. NTSTATUS Status;
  170. PNDS_RESPONSE_SUBORDINATE_ENTRY pSubEntry;
  171. PBYTE pbRaw;
  172. DWORD dwStrLen, dwEntries;
  173. dwEntries = pSubList->SubordinateEntries;
  174. printf( "======================== Subordinate List (%d) ========================\n", dwEntries );
  175. pSubEntry = ( PNDS_RESPONSE_SUBORDINATE_ENTRY )
  176. ( ( (BYTE *)pSubList ) + sizeof( NDS_RESPONSE_SUBORDINATE_LIST ) );
  177. while ( dwEntries ) {
  178. printf( "EntryID (0x%08lx),\tFlags (0x%08lx)\n",
  179. pSubEntry->EntryId, pSubEntry->Flags );
  180. printf( "Subordinate Count (%d),\tMod Time (0x%08lx)\n",
  181. pSubEntry->SubordinateCount, pSubEntry->ModificationTime );
  182. pbRaw = (BYTE *) pSubEntry;
  183. pbRaw += sizeof( NDS_RESPONSE_SUBORDINATE_ENTRY );
  184. dwStrLen = * ( DWORD * ) pbRaw;
  185. pbRaw += sizeof( DWORD );
  186. printf( "Class Name: %S\t", pbRaw );
  187. pbRaw += ROUNDUP4( dwStrLen );
  188. dwStrLen = * ( DWORD * ) pbRaw;
  189. pbRaw += sizeof( DWORD );
  190. printf( "Object Name: %S\n", pbRaw );
  191. pSubEntry = ( PNDS_RESPONSE_SUBORDINATE_ENTRY ) ( pbRaw + ROUNDUP4( dwStrLen ) );
  192. dwEntries--;
  193. printf( "-----------------------------------------------------------------------\n" );
  194. }
  195. return;
  196. }