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.

1956 lines
62 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. dfskd.c
  5. Abstract:
  6. Dfs Kernel Debugger extension
  7. Author:
  8. Milan Shah (milans) 21-Aug-1995
  9. Revision History:
  10. 21-Aug-1995 Milans Created
  11. 30-Aug-1997 JHarper Updated
  12. --*/
  13. #include <ntos.h>
  14. #include <nturtl.h>
  15. #include "ntverp.h"
  16. #include <windows.h>
  17. #include <wdbgexts.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <stdio.h>
  21. #include "nodetype.h"
  22. #include "dfsmrshl.h"
  23. #include "dfsfsctl.h"
  24. #include "pkt.h"
  25. #include "dfslpc.h"
  26. #include "spcsup.h"
  27. #include "sitesup.h"
  28. #include "ipsup.h"
  29. #include "dfsstruc.h"
  30. #include "fsctrl.h"
  31. #include "attach.h"
  32. #include "fcbsup.h"
  33. #include <kdextlib.h>
  34. #define PRINTF dprintf
  35. #define IPRINTF DoIndent(); dprintf
  36. #define IPRINTSTRINGW DoIndent(); wPrintStringW
  37. #define NTC_UNDEFINED ((NODE_TYPE_CODE)0x0000)
  38. #define DSFS_NTC_DATA_HEADER ((NODE_TYPE_CODE)0x0D01)
  39. #define DSFS_NTC_IRP_CONTEXT ((NODE_TYPE_CODE)0x0D02)
  40. #define DSFS_NTC_REFERRAL ((NODE_TYPE_CODE)0x0D03)
  41. #define DSFS_NTC_VCB ((NODE_TYPE_CODE)0x0D04)
  42. #define DSFS_NTC_PROVIDER ((NODE_TYPE_CODE)0x0D05)
  43. #define DSFS_NTC_FCB_HASH ((NODE_TYPE_CODE)0x0D06)
  44. #define DSFS_NTC_FCB ((NODE_TYPE_CODE)0x0D07)
  45. #define DSFS_NTC_DNR_CONTEXT ((NODE_TYPE_CODE)0x0D08)
  46. #define DSFS_NTC_PKT ((NODE_TYPE_CODE)0x0D09)
  47. #define DSFS_NTC_PKT_ENTRY ((NODE_TYPE_CODE)0x0D0A)
  48. #define DSFS_NTC_PKT_STUB ((NODE_TYPE_CODE)0x0D0B)
  49. #define DSFS_NTC_INSTRUM ((NODE_TYPE_CODE)0x0D0C)
  50. #define DSFS_NTC_INSTRUM_FREED ((NODE_TYPE_CODE)0x0D0D)
  51. #define DSFS_NTC_PWSTR ((NODE_TYPE_CODE)0x0D0E)
  52. #define FIELD_NAME_LENGTH 30
  53. #define NewLineForFields(FieldNo) \
  54. ((((FieldNo) % s_NoOfColumns) == 0) ? NewLine : FieldSeparator)
  55. char *NewLine = "\n";
  56. char *FieldSeparator = " ";
  57. BOOLEAN wGetData( ULONG_PTR dwAddress, PVOID ptr, ULONG size);
  58. BOOL wGetString( ULONG_PTR dwAddress, PSZ buf );
  59. BOOL wPrintStringW( IN LPSTR msg OPTIONAL, IN PUNICODE_STRING pStr, IN BOOL nl );
  60. BOOL wPrintStringA( IN LPSTR msg OPTIONAL, IN PANSI_STRING pStr, IN BOOL nl );
  61. BOOL wPrintLargeInt(LARGE_INTEGER *bigint);
  62. #define MAX_ENTRIES 100
  63. /*
  64. * Dfs global variables.
  65. *
  66. */
  67. #define NO_SYMBOLS_MESSAGE \
  68. "Unable to get address of Dfs!DfsData - do you have symbols?\n"
  69. LPSTR ExtensionNames[] = {
  70. "Dfs debugger extensions",
  71. 0
  72. };
  73. LPSTR Extensions[] = {
  74. "DfsData - dumps Dfs!DfsData",
  75. "Pkt - dumps the global Pkt",
  76. "SpecialTable - dumps the Special table",
  77. "FtDfsTable - dumps the FtDfs table",
  78. "SiteTable - dumps the Site table",
  79. "IpTable - dumps the Ip table",
  80. "FcbTable - dumps all the Dfs FCBs",
  81. "VdoList - dumps all the Dfs Volume Objects (attached device objects)",
  82. "VcbList - dumps all the Vcbs & Dfs Device Objects (net used objects)",
  83. "Dump - dump a data structure. Type in 'dfskd.dump' for more info",
  84. "Dumpdfs address -- dumps DfsData, prefix table",
  85. 0
  86. };
  87. ENUM_VALUE_DESCRIPTOR DfsOperationalStateEnum[] = {
  88. {DFS_STATE_UNINITIALIZED, "Dfs State Uninitialized"},
  89. {DFS_STATE_INITIALIZED, "Dfs State Initialized"},
  90. {DFS_STATE_STARTED, "Dfs Started"},
  91. {DFS_STATE_STOPPING, "Dfs Stopping"},
  92. {DFS_STATE_STOPPED, "Dfs Stopped"},
  93. 0
  94. };
  95. ENUM_VALUE_DESCRIPTOR DfsMachineStateEnum[] = {
  96. {DFS_UNKNOWN, "Dfs State Unknown"},
  97. {DFS_CLIENT, "Dfs Client"},
  98. {DFS_SERVER, "Dfs Server"},
  99. {DFS_ROOT_SERVER, "Dfs Root"},
  100. 0
  101. };
  102. ENUM_VALUE_DESCRIPTOR LpcPortStateEnum[] = {
  103. {LPC_STATE_UNINITIALIZED, "Unitialized"},
  104. {LPC_STATE_INITIALIZING, "Initializing"},
  105. {LPC_STATE_INITIALIZED, "Initialized"},
  106. 0
  107. };
  108. ENUM_VALUE_DESCRIPTOR LvStateEnum[] = {
  109. {LV_UNINITIALIZED,"Local Vols Uninitialized"},
  110. {LV_INITSCHEDULED,"Local Vols init scheduled"},
  111. {LV_INITINPROGRESS,"Local Vols init in progress"},
  112. {LV_INITIALIZED,"Local Vols Initialized"},
  113. {LV_VALIDATED,"Local Vols Validated with DC"},
  114. 0
  115. };
  116. /*
  117. * DFS_DATA
  118. *
  119. */
  120. FIELD_DESCRIPTOR DfsDataFields[] = {
  121. FIELD3(FieldTypeShort,DFS_DATA,NodeTypeCode),
  122. FIELD3(FieldTypeShort,DFS_DATA,NodeByteSize),
  123. FIELD3(FieldTypeStruct,DFS_DATA,AVdoQueue),
  124. FIELD3(FieldTypePointer,DFS_DATA,DriverObject),
  125. FIELD3(FieldTypePointer,DFS_DATA,FileSysDeviceObject),
  126. FIELD3(FieldTypePointer,DFS_DATA,pProvider),
  127. FIELD3(FieldTypeULong,DFS_DATA,cProvider),
  128. FIELD3(FieldTypeULong,DFS_DATA,maxProvider),
  129. FIELD3(FieldTypeStruct,DFS_DATA,Resource),
  130. FIELD3(FieldTypeUnicodeString,DFS_DATA,PrincipalName),
  131. FIELD3(FieldTypeUnicodeString,DFS_DATA,NetBIOSName),
  132. FIELD4(FieldTypeEnum,DFS_DATA,OperationalState,DfsOperationalStateEnum),
  133. FIELD4(FieldTypeEnum,DFS_DATA,MachineState,DfsMachineStateEnum),
  134. FIELD3(FieldTypeBoolean,DFS_DATA,IsDC),
  135. FIELD4(FieldTypeEnum,DFS_DATA,LvState,LvStateEnum),
  136. FIELD3(FieldTypeStruct,DFS_DATA,Pkt),
  137. FIELD3(FieldTypePointer,DFS_DATA,FcbHashTable),
  138. FIELD3(FieldTypePointer,DFS_DATA,SiteHashTable),
  139. FIELD3(FieldTypePointer,DFS_DATA,IpHashTable),
  140. FIELD3(FieldTypePointer,DFS_DATA,SpcHashTable),
  141. FIELD3(FieldTypePointer,DFS_DATA,FtDfsHashTable),
  142. FIELD3(FieldTypeStruct,DFS_DATA,DfsLpcInfo),
  143. 0
  144. };
  145. /*
  146. * DFS_PKT
  147. *
  148. */
  149. FIELD_DESCRIPTOR DfsPktFields[] = {
  150. FIELD3(FieldTypeUShort,DFS_PKT,NodeTypeCode),
  151. FIELD3(FieldTypeUShort,DFS_PKT,NodeByteSize),
  152. FIELD3(FieldTypeStruct,DFS_PKT,Resource),
  153. FIELD3(FieldTypeStruct,DFS_PKT,UseCountLock),
  154. FIELD3(FieldTypeULong,DFS_PKT,EntryCount),
  155. FIELD3(FieldTypeStruct,DFS_PKT,EntryList),
  156. FIELD3(FieldTypePointer,DFS_PKT,DomainPktEntry),
  157. FIELD3(FieldTypeStruct,DFS_PKT,LocalVolTable),
  158. FIELD3(FieldTypeStruct,DFS_PKT,PrefixTable),
  159. FIELD3(FieldTypeStruct,DFS_PKT,ShortPrefixTable),
  160. FIELD3(FieldTypeStruct,DFS_PKT,DSMachineTable),
  161. 0
  162. };
  163. /*
  164. * DFS_PKT_ENTRY
  165. *
  166. */
  167. BIT_MASK_DESCRIPTOR PktEntryType[] = {
  168. {PKT_ENTRY_TYPE_CAIRO, "Cairo Volume"},
  169. {PKT_ENTRY_TYPE_MACHINE, "Machine Volume"},
  170. {PKT_ENTRY_TYPE_NONCAIRO, "Non-Cairo Volume"},
  171. {PKT_ENTRY_TYPE_OUTSIDE_MY_DOM, "Inter-Domain Volume"},
  172. {PKT_ENTRY_TYPE_REFERRAL_SVC, "Referral Service (DC)"},
  173. {PKT_ENTRY_TYPE_PERMANENT, "Permanent Entry"},
  174. {PKT_ENTRY_TYPE_LOCAL,"Local Volume"},
  175. {PKT_ENTRY_TYPE_LOCAL_XPOINT,"Local Exit Point"},
  176. {PKT_ENTRY_TYPE_MACH_SHARE,"Local Machine Share"},
  177. {PKT_ENTRY_TYPE_OFFLINE,"Offline Volume"},
  178. 0
  179. };
  180. FIELD_DESCRIPTOR DfsPktEntryFields[] = {
  181. FIELD3(FieldTypeUShort,DFS_PKT_ENTRY,NodeTypeCode),
  182. FIELD3(FieldTypeUShort,DFS_PKT_ENTRY,NodeByteSize),
  183. FIELD4(FieldTypeDWordBitMask,DFS_PKT_ENTRY,Type,PktEntryType),
  184. FIELD3(FieldTypeULong,DFS_PKT_ENTRY,USN),
  185. FIELD3(FieldTypeUnicodeString,DFS_PKT_ENTRY,Id.Prefix),
  186. FIELD3(FieldTypeUnicodeString,DFS_PKT_ENTRY,Id.ShortPrefix),
  187. FIELD3(FieldTypeULong,DFS_PKT_ENTRY,Info.Timeout),
  188. FIELD3(FieldTypeULong,DFS_PKT_ENTRY,Info.ServiceCount),
  189. FIELD3(FieldTypePointer,DFS_PKT_ENTRY,Info.ServiceList),
  190. FIELD3(FieldTypeULong,DFS_PKT_ENTRY,UseCount),
  191. FIELD3(FieldTypeULong,DFS_PKT_ENTRY,FileOpenCount),
  192. FIELD3(FieldTypePointer,DFS_PKT_ENTRY,ActiveService),
  193. FIELD3(FieldTypePointer,DFS_PKT_ENTRY,LocalService),
  194. FIELD3(FieldTypePointer,DFS_PKT_ENTRY,Superior),
  195. FIELD3(FieldTypeULong,DFS_PKT_ENTRY,SubordinateCount),
  196. FIELD3(FieldTypeStruct,DFS_PKT_ENTRY,SubordinateList),
  197. FIELD3(FieldTypeStruct,DFS_PKT_ENTRY,SiblingLink),
  198. FIELD3(FieldTypePointer,DFS_PKT_ENTRY,ClosestDC),
  199. FIELD3(FieldTypeStruct,DFS_PKT_ENTRY,ChildList),
  200. FIELD3(FieldTypeStruct,DFS_PKT_ENTRY,NextLink),
  201. FIELD3(FieldTypeStruct,DFS_PKT_ENTRY,PrefixTableEntry),
  202. 0
  203. };
  204. /*
  205. * DFS_SERVICE
  206. *
  207. */
  208. BIT_MASK_DESCRIPTOR ServiceType[] = {
  209. {DFS_SERVICE_TYPE_MASTER, "Master Svc"},
  210. {DFS_SERVICE_TYPE_READONLY, "Read-Only Svc"},
  211. {DFS_SERVICE_TYPE_LOCAL, "Local Svc"},
  212. {DFS_SERVICE_TYPE_REFERRAL, "Referral Svc"},
  213. {DFS_SERVICE_TYPE_ACTIVE, "Active Svc"},
  214. {DFS_SERVICE_TYPE_DOWN_LEVEL, "Down-level Svc"},
  215. {DFS_SERVICE_TYPE_COSTLIER, "Costlier than previous"},
  216. {DFS_SERVICE_TYPE_OFFLINE, "Svc Offline"},
  217. 0
  218. };
  219. BIT_MASK_DESCRIPTOR ServiceCapability[] = {
  220. {PROV_DFS_RDR, "Use Dfs Rdr"},
  221. {PROV_STRIP_PREFIX, "Strip Prefix (downlevel or local) Svc"},
  222. 0
  223. };
  224. FIELD_DESCRIPTOR DfsServiceFields[] = {
  225. FIELD4(FieldTypeDWordBitMask,DFS_SERVICE,Type,ServiceType),
  226. FIELD4(FieldTypeDWordBitMask,DFS_SERVICE,Capability,ServiceCapability),
  227. FIELD3(FieldTypeULong,DFS_SERVICE,Status),
  228. FIELD3(FieldTypeULong,DFS_SERVICE,ProviderId),
  229. FIELD3(FieldTypeULong,DFS_SERVICE,Cost),
  230. FIELD3(FieldTypePointer,DFS_SERVICE,ConnFile),
  231. FIELD3(FieldTypePointer,DFS_SERVICE,pProvider),
  232. FIELD3(FieldTypePointer,DFS_SERVICE,pMachEntry),
  233. FIELD3(FieldTypeUnicodeString,DFS_SERVICE,Name),
  234. FIELD3(FieldTypeUnicodeString,DFS_SERVICE,Address),
  235. FIELD3(FieldTypeUnicodeString,DFS_SERVICE,StgId),
  236. 0
  237. };
  238. /*
  239. * DFS_MACHINE_ENTRY
  240. *
  241. */
  242. FIELD_DESCRIPTOR DfsMachineEntryFields[] = {
  243. FIELD3(FieldTypePointer,DFS_MACHINE_ENTRY,pMachine),
  244. FIELD3(FieldTypeUnicodeString,DFS_MACHINE_ENTRY,MachineName),
  245. FIELD3(FieldTypeULong,DFS_MACHINE_ENTRY,UseCount),
  246. FIELD3(FieldTypeULong,DFS_MACHINE_ENTRY,ConnectionCount),
  247. 0
  248. };
  249. /*
  250. * DS_MACHINE
  251. *
  252. */
  253. FIELD_DESCRIPTOR DsMachineFields[] = {
  254. FIELD3(FieldTypeGuid,DS_MACHINE,guidSite),
  255. FIELD3(FieldTypeGuid,DS_MACHINE,guidMachine),
  256. FIELD3(FieldTypeULong,DS_MACHINE,grfFlags),
  257. FIELD3(FieldTypePWStr,DS_MACHINE,pwszShareName),
  258. FIELD3(FieldTypeULong,DS_MACHINE,cPrincipals),
  259. FIELD3(FieldTypePointer,DS_MACHINE,prgpwszPrincipals),
  260. FIELD3(FieldTypeULong,DS_MACHINE,cTransports),
  261. FIELD3(FieldTypeStruct,DS_MACHINE,rpTrans),
  262. 0
  263. };
  264. /*
  265. * DFS_LPC_INFO
  266. *
  267. */
  268. FIELD_DESCRIPTOR LpcInfoFields[] = {
  269. FIELD3(FieldTypeUnicodeString,DFS_LPC_INFO,LpcPortName),
  270. FIELD4(FieldTypeEnum,DFS_LPC_INFO,LpcPortState,LpcPortStateEnum),
  271. FIELD3(FieldTypePointer,DFS_LPC_INFO,LpcPortHandle),
  272. 0
  273. };
  274. /*
  275. * PROVIDER_DEF
  276. *
  277. */
  278. FIELD_DESCRIPTOR ProviderDefFields[] = {
  279. FIELD3(FieldTypeUShort,PROVIDER_DEF,NodeTypeCode),
  280. FIELD3(FieldTypeUShort,PROVIDER_DEF,NodeByteSize),
  281. FIELD3(FieldTypeUShort,PROVIDER_DEF,eProviderId),
  282. FIELD4(FieldTypeDWordBitMask,PROVIDER_DEF,fProvCapability,ServiceCapability),
  283. FIELD3(FieldTypeUnicodeString,PROVIDER_DEF,DeviceName),
  284. FIELD3(FieldTypePointer,PROVIDER_DEF,DeviceObject),
  285. FIELD3(FieldTypePointer,PROVIDER_DEF,FileObject),
  286. 0
  287. };
  288. /*
  289. * DFS_VOLUME_OBJECT
  290. *
  291. */
  292. FIELD_DESCRIPTOR DfsVolumeObjectFields[] = {
  293. FIELD3(FieldTypeStruct,DFS_VOLUME_OBJECT,DeviceObject),
  294. FIELD3(FieldTypeULong,DFS_VOLUME_OBJECT,AttachCount),
  295. FIELD3(FieldTypeStruct,DFS_VOLUME_OBJECT,VdoLinks),
  296. FIELD3(FieldTypeStruct,DFS_VOLUME_OBJECT,Provider),
  297. FIELD3(FieldTypeUnicodeString,DFS_VOLUME_OBJECT,Provider.DeviceName),
  298. FIELD3(FieldTypePointer,DFS_VOLUME_OBJECT,Provider.DeviceObject),
  299. FIELD3(FieldTypePointer,DFS_VOLUME_OBJECT,Provider.FileObject),
  300. 0
  301. };
  302. /*
  303. * DFS_PREFIX_TABLE
  304. *
  305. */
  306. FIELD_DESCRIPTOR DfsPrefixTableFields[] = {
  307. FIELD3(FieldTypeBoolean,DFS_PREFIX_TABLE,CaseSensitive),
  308. FIELD3(FieldTypePointer,DFS_PREFIX_TABLE,NamePageList.pFirstPage),
  309. FIELD3(FieldTypePointer,DFS_PREFIX_TABLE,NextEntry),
  310. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,RootEntry),
  311. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[0].NoOfEntries),
  312. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[0].SentinelEntry),
  313. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[1].NoOfEntries),
  314. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[1].SentinelEntry),
  315. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[2].NoOfEntries),
  316. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[2].SentinelEntry),
  317. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[3].NoOfEntries),
  318. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[3].SentinelEntry),
  319. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[4].NoOfEntries),
  320. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[4].SentinelEntry),
  321. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[5].NoOfEntries),
  322. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[5].SentinelEntry),
  323. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[6].NoOfEntries),
  324. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[6].SentinelEntry),
  325. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[7].NoOfEntries),
  326. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[7].SentinelEntry),
  327. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[8].NoOfEntries),
  328. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[8].SentinelEntry),
  329. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[9].NoOfEntries),
  330. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[9].SentinelEntry),
  331. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[10].NoOfEntries),
  332. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[10].SentinelEntry),
  333. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[11].NoOfEntries),
  334. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[11].SentinelEntry),
  335. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[12].NoOfEntries),
  336. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[12].SentinelEntry),
  337. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[13].NoOfEntries),
  338. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[13].SentinelEntry),
  339. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[14].NoOfEntries),
  340. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[14].SentinelEntry),
  341. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[15].NoOfEntries),
  342. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[15].SentinelEntry),
  343. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[16].NoOfEntries),
  344. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[16].SentinelEntry),
  345. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[17].NoOfEntries),
  346. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[17].SentinelEntry),
  347. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[18].NoOfEntries),
  348. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[18].SentinelEntry),
  349. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[19].NoOfEntries),
  350. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[19].SentinelEntry),
  351. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[20].NoOfEntries),
  352. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[20].SentinelEntry),
  353. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[21].NoOfEntries),
  354. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[21].SentinelEntry),
  355. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[22].NoOfEntries),
  356. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[22].SentinelEntry),
  357. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[23].NoOfEntries),
  358. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[23].SentinelEntry),
  359. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[24].NoOfEntries),
  360. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[24].SentinelEntry),
  361. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[25].NoOfEntries),
  362. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[25].SentinelEntry),
  363. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[26].NoOfEntries),
  364. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[26].SentinelEntry),
  365. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[27].NoOfEntries),
  366. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[27].SentinelEntry),
  367. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[28].NoOfEntries),
  368. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[28].SentinelEntry),
  369. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[29].NoOfEntries),
  370. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[29].SentinelEntry),
  371. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[30].NoOfEntries),
  372. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[30].SentinelEntry),
  373. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[31].NoOfEntries),
  374. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[31].SentinelEntry),
  375. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[32].NoOfEntries),
  376. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[32].SentinelEntry),
  377. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[33].NoOfEntries),
  378. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[33].SentinelEntry),
  379. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[34].NoOfEntries),
  380. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[34].SentinelEntry),
  381. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[35].NoOfEntries),
  382. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[35].SentinelEntry),
  383. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[36].NoOfEntries),
  384. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[36].SentinelEntry),
  385. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[37].NoOfEntries),
  386. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[37].SentinelEntry),
  387. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[38].NoOfEntries),
  388. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[38].SentinelEntry),
  389. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[39].NoOfEntries),
  390. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[39].SentinelEntry),
  391. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[40].NoOfEntries),
  392. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[40].SentinelEntry),
  393. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[41].NoOfEntries),
  394. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[41].SentinelEntry),
  395. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[42].NoOfEntries),
  396. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[42].SentinelEntry),
  397. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[43].NoOfEntries),
  398. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[43].SentinelEntry),
  399. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[44].NoOfEntries),
  400. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[44].SentinelEntry),
  401. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[45].NoOfEntries),
  402. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[45].SentinelEntry),
  403. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[46].NoOfEntries),
  404. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[46].SentinelEntry),
  405. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[47].NoOfEntries),
  406. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[47].SentinelEntry),
  407. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[48].NoOfEntries),
  408. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[48].SentinelEntry),
  409. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[49].NoOfEntries),
  410. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[49].SentinelEntry),
  411. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[50].NoOfEntries),
  412. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[50].SentinelEntry),
  413. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[51].NoOfEntries),
  414. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[51].SentinelEntry),
  415. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[52].NoOfEntries),
  416. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[52].SentinelEntry),
  417. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[53].NoOfEntries),
  418. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[53].SentinelEntry),
  419. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[54].NoOfEntries),
  420. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[54].SentinelEntry),
  421. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[55].NoOfEntries),
  422. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[55].SentinelEntry),
  423. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE,Buckets[56].NoOfEntries),
  424. FIELD3(FieldTypeStruct,DFS_PREFIX_TABLE,Buckets[56].SentinelEntry),
  425. 0
  426. };
  427. /*
  428. * DFS_PREFIX_TABLE_ENTRY
  429. *
  430. */
  431. FIELD_DESCRIPTOR DfsPrefixTableEntryFields[] = {
  432. FIELD3(FieldTypePointer,DFS_PREFIX_TABLE_ENTRY,pParentEntry),
  433. FIELD3(FieldTypePointer,DFS_PREFIX_TABLE_ENTRY,pNextEntry),
  434. FIELD3(FieldTypePointer,DFS_PREFIX_TABLE_ENTRY,pPrevEntry),
  435. FIELD3(FieldTypePointer,DFS_PREFIX_TABLE_ENTRY,pFirstChildEntry),
  436. FIELD3(FieldTypePointer,DFS_PREFIX_TABLE_ENTRY,pSiblingEntry),
  437. FIELD3(FieldTypeULong,DFS_PREFIX_TABLE_ENTRY,NoOfChildren),
  438. FIELD3(FieldTypeUnicodeString,DFS_PREFIX_TABLE_ENTRY,PathSegment),
  439. FIELD3(FieldTypePointer,DFS_PREFIX_TABLE_ENTRY,pData),
  440. 0
  441. };
  442. FIELD_DESCRIPTOR DfsLocalVolEntryFields[] = {
  443. FIELD3(FieldTypeStruct,DFS_LOCAL_VOL_ENTRY,PktEntry),
  444. FIELD3(FieldTypeUnicodeString,DFS_LOCAL_VOL_ENTRY,LocalPath),
  445. FIELD3(FieldTypeUnicodeString,DFS_LOCAL_VOL_ENTRY,ShareName),
  446. FIELD3(FieldTypeStruct,DFS_LOCAL_VOL_ENTRY,PrefixTableEntry),
  447. 0
  448. };
  449. /*
  450. * DFS_FCB
  451. *
  452. */
  453. FIELD_DESCRIPTOR FcbFields[] = {
  454. FIELD3(FieldTypeUShort, DFS_FCB, NodeTypeCode),
  455. FIELD3(FieldTypeUShort, DFS_FCB, NodeByteSize),
  456. FIELD3(FieldTypeUnicodeString, DFS_FCB, FullFileName),
  457. FIELD3(FieldTypePointer, DFS_FCB, FileObject),
  458. 0
  459. };
  460. STRUCT_DESCRIPTOR Structs[] = {
  461. STRUCT(DFS_DATA,DfsDataFields),
  462. STRUCT(DFS_PKT,DfsPktFields),
  463. STRUCT(DFS_PKT_ENTRY,DfsPktEntryFields),
  464. STRUCT(DFS_SERVICE,DfsServiceFields),
  465. STRUCT(DFS_MACHINE_ENTRY,DfsMachineEntryFields),
  466. STRUCT(DS_MACHINE,DsMachineFields),
  467. STRUCT(PROVIDER_DEF,ProviderDefFields),
  468. STRUCT(DFS_VOLUME_OBJECT,DfsVolumeObjectFields),
  469. STRUCT(DFS_PREFIX_TABLE,DfsPrefixTableFields),
  470. STRUCT(DFS_PREFIX_TABLE_ENTRY,DfsPrefixTableEntryFields),
  471. STRUCT(DFS_LOCAL_VOL_ENTRY,DfsLocalVolEntryFields),
  472. STRUCT(DFS_LPC_INFO,LpcInfoFields),
  473. STRUCT(DFS_FCB,FcbFields),
  474. 0
  475. };
  476. /*
  477. * Dfs specific dump routines
  478. *
  479. */
  480. VOID
  481. dumplist(
  482. ULONG_PTR dwListEntryAddress,
  483. DWORD linkOffset,
  484. VOID (*dumpRoutine)(ULONG_PTR dwStructAddress)
  485. );
  486. VOID
  487. dumpPktEntry(
  488. ULONG_PTR dwAddress
  489. );
  490. VOID
  491. PktEntryDump(
  492. ULONG_PTR dwAddress
  493. );
  494. VOID
  495. dumpFcb(
  496. ULONG_PTR dwAddress
  497. );
  498. VOID
  499. dumpVcb(
  500. ULONG_PTR dwAddress
  501. );
  502. VOID
  503. dumpVdo(
  504. ULONG_PTR dwAddress
  505. );
  506. VOID
  507. dumpSiteInfo(
  508. ULONG_PTR dwAddress
  509. );
  510. VOID
  511. dumpSpcInfo(
  512. ULONG_PTR dwAddress
  513. );
  514. VOID
  515. dumpIpInfo(
  516. ULONG_PTR dwAddress
  517. );
  518. VOID
  519. DumpDfsPrefixTableEntry(
  520. ULONG_PTR dwAddress,
  521. VOID (*DispFunc)(ULONG_PTR dwAddress)
  522. );
  523. VOID
  524. DumpUnicodePrefixTable(
  525. ULONG_PTR dwAddress
  526. );
  527. VOID
  528. DumpUnicodePrefixTableEntry(
  529. ULONG_PTR dwAddress
  530. );
  531. VOID
  532. DoIndent(
  533. VOID
  534. );
  535. VOID
  536. MyDumpPktEntry(
  537. ULONG_PTR dwAddress
  538. );
  539. VOID
  540. MyDumpLocalVolEntry(
  541. ULONG_PTR dwAddress
  542. );
  543. VOID
  544. MyDumpServices(
  545. ULONG_PTR dwAddress,
  546. ULONG ServiceCount
  547. );
  548. /*
  549. * globals
  550. */
  551. INT Indent = 0;
  552. /*
  553. * dfsdata : Routine to dump the global dfs data structure
  554. *
  555. */
  556. BOOL
  557. dfsdata(
  558. ULONG_PTR dwCurrentPC,
  559. PWINDBG_EXTENSION_APIS lpExtensionApis,
  560. LPSTR lpArgumentString
  561. )
  562. {
  563. ULONG_PTR dwAddress;
  564. dwAddress = (GetExpression)("dfs!DfsData");
  565. if (dwAddress) {
  566. DFS_DATA DfsData;
  567. if (wGetData( dwAddress, &DfsData, sizeof(DfsData) )) {
  568. PrintStructFields( dwAddress, &DfsData, DfsDataFields);
  569. } else {
  570. PRINTF( "Unable to read DfsData @ %08lx\n", dwAddress );
  571. }
  572. } else {
  573. PRINTF( NO_SYMBOLS_MESSAGE );
  574. }
  575. return( TRUE );
  576. }
  577. /*
  578. * pkt : Routine to dump the Dfs PKT data structure
  579. *
  580. */
  581. BOOL
  582. pkt(
  583. ULONG_PTR dwCurrentPC,
  584. PWINDBG_EXTENSION_APIS lpExtensionApis,
  585. LPSTR lpArgumentString
  586. )
  587. {
  588. ULONG_PTR dwAddress;
  589. //
  590. // Figure out the address of the Pkt. This is an offset within
  591. // dfs!DfsData.
  592. //
  593. dwAddress = (GetExpression)("dfs!DfsData");
  594. if (dwAddress) {
  595. DFS_PKT pkt;
  596. dwAddress += FIELD_OFFSET(DFS_DATA, Pkt);
  597. if (wGetData(dwAddress,&pkt,sizeof(pkt))) {
  598. PrintStructFields( dwAddress, &pkt, DfsPktFields );
  599. dwAddress += FIELD_OFFSET(DFS_PKT, EntryList);
  600. dumplist(
  601. dwAddress,
  602. FIELD_OFFSET(DFS_PKT_ENTRY,Link),
  603. dumpPktEntry);
  604. }
  605. } else {
  606. PRINTF( NO_SYMBOLS_MESSAGE );
  607. }
  608. return( TRUE );
  609. }
  610. /*
  611. * dumpPktEntry : Routine suitable as argument for dumplist; used to dump
  612. * list of pkt entries.
  613. *
  614. */
  615. VOID
  616. dumpPktEntry(
  617. ULONG_PTR dwAddress
  618. )
  619. {
  620. DFS_PKT_ENTRY pktEntry;
  621. if (wGetData(dwAddress, &pktEntry, sizeof(DFS_PKT_ENTRY))) {
  622. PRINTF( "\n--- Pkt Entry @ %08lx\n", dwAddress);
  623. wPrintStringW("Prefix : ", &pktEntry.Id.Prefix, TRUE);
  624. wPrintStringW("ShortPrefix : ", &pktEntry.Id.ShortPrefix, TRUE);
  625. //
  626. // Print the local service, if any
  627. //
  628. if (pktEntry.LocalService != NULL) {
  629. DFS_SERVICE Svc;
  630. PRINTF( " Local Svc @%08lx : ",pktEntry.LocalService);
  631. if (wGetData( (ULONG_PTR)pktEntry.LocalService, &Svc, sizeof(Svc))) {
  632. wPrintStringW("Storage Id = ", &Svc.Address, TRUE);
  633. } else {
  634. PRINTF( "Storage Id = ?\n");
  635. }
  636. }
  637. //
  638. // Now, print the service list
  639. //
  640. if (pktEntry.Info.ServiceCount != 0) {
  641. ULONG i;
  642. for (i = 0; i < pktEntry.Info.ServiceCount; i++) {
  643. DFS_SERVICE Svc;
  644. ULONG_PTR dwServiceAddress;
  645. if (CheckControlC())
  646. return;
  647. dwServiceAddress =
  648. ((ULONG_PTR)pktEntry.Info.ServiceList) +
  649. i * sizeof(DFS_SERVICE);
  650. PRINTF( " Service %d @%08lx : ",i, dwServiceAddress);
  651. if (wGetData(dwServiceAddress, &Svc, sizeof(Svc))) {
  652. wPrintStringW( "Address =", &Svc.Address, TRUE );
  653. } else {
  654. PRINTF( "Address = ?\n");
  655. }
  656. }
  657. }
  658. } else {
  659. PRINTF( "Unable to get Pkt Entry @%08lx\n", dwAddress);
  660. }
  661. }
  662. VOID
  663. PktEntryDump(ULONG_PTR dwAddress)
  664. {
  665. DFS_PKT_ENTRY pktEntry;
  666. if (wGetData(dwAddress, &pktEntry, sizeof(DFS_PKT_ENTRY))) {
  667. PRINTF( "\n--- Pkt Entry @ %08lx\n", dwAddress);
  668. wPrintStringW("Prefix : ", &pktEntry.Id.Prefix, TRUE);
  669. wPrintStringW("ShortPrefix : ", &pktEntry.Id.ShortPrefix, TRUE);
  670. //
  671. // Print the local service, if any
  672. //
  673. if (pktEntry.LocalService != NULL) {
  674. DFS_SERVICE Svc;
  675. PRINTF( " Local Svc @%08lx : ",pktEntry.LocalService);
  676. if (wGetData( (ULONG_PTR)pktEntry.LocalService, &Svc, sizeof(Svc))) {
  677. wPrintStringW("Storage Id = ", &Svc.Address, TRUE);
  678. } else {
  679. PRINTF( "Storage Id = ?\n");
  680. }
  681. }
  682. } else {
  683. PRINTF( "Unable to get Pkt Entry @%08lx\n", dwAddress);
  684. }
  685. }
  686. /*
  687. * fcbtable : Routine to dump the dfs fcb hash table
  688. *
  689. */
  690. BOOL
  691. fcbtable(
  692. DWORD dwCurrentPC,
  693. PWINDBG_EXTENSION_APIS lpExtensionApis,
  694. LPSTR lpArgumentString
  695. )
  696. {
  697. DWORD_PTR dwAddress;
  698. //
  699. // Figure out the address of the Pkt. This is an offset withing
  700. // Dfs!DfsData.
  701. //
  702. dwAddress = (GetExpression)("Dfs!DfsData");
  703. if (dwAddress) {
  704. DFS_DATA DfsData;
  705. if (wGetData(dwAddress, &DfsData, sizeof(DFS_DATA))) {
  706. FCB_HASH_TABLE FcbTable;
  707. dwAddress = (DWORD_PTR) DfsData.FcbHashTable;
  708. if (wGetData(dwAddress, &FcbTable, sizeof(FCB_HASH_TABLE))) {
  709. ULONG i, cBuckets;
  710. DWORD_PTR dwListHeadAddress;
  711. cBuckets = FcbTable.HashMask + 1;
  712. dwListHeadAddress =
  713. dwAddress + FIELD_OFFSET(FCB_HASH_TABLE, HashBuckets);
  714. PRINTF(
  715. "+++ Fcb Hash Table @ %p (%d Buckets) +++\n",
  716. dwAddress, cBuckets);
  717. for (i = 0; i < cBuckets; i++) {
  718. if (CheckControlC())
  719. return TRUE;
  720. PRINTF( "--- Bucket(%d)\n", i );
  721. dumplist(
  722. dwListHeadAddress,
  723. FIELD_OFFSET(DFS_FCB, HashChain),
  724. dumpFcb);
  725. dwListHeadAddress += sizeof(LIST_ENTRY);
  726. }
  727. PRINTF("--- Fcb Hash Table @ %08lx ---\n", dwAddress);
  728. } else {
  729. PRINTF( "Unable to read FcbTable @%08lx\n", dwAddress );
  730. }
  731. } else {
  732. PRINTF( "Unable to read DfsData @%08lx\n", dwAddress);
  733. }
  734. } else {
  735. PRINTF( NO_SYMBOLS_MESSAGE );
  736. }
  737. return( TRUE );
  738. }
  739. /*
  740. * dumpFcb : Routine suitable as argument to dumplist; used to dump list of
  741. * Fcbs
  742. *
  743. */
  744. VOID
  745. dumpFcb(
  746. DWORD_PTR dwAddress
  747. )
  748. {
  749. DFS_FCB fcb;
  750. if (wGetData( dwAddress, &fcb, sizeof(fcb))) {
  751. PRINTF("\nFcb @ %08lx\n", dwAddress);
  752. PrintStructFields( dwAddress, &fcb, FcbFields );
  753. } else {
  754. PRINTF("\nUnable to read Fcb @ %08lx\n", dwAddress);
  755. }
  756. }
  757. /*
  758. * vdolist : Routine to dump out all the Dfs Volume Device Objects (ie, the
  759. * attached device objects)
  760. *
  761. */
  762. BOOL
  763. vdolist(
  764. ULONG_PTR dwCurrentPC,
  765. PWINDBG_EXTENSION_APIS lpExtensionApis,
  766. LPSTR lpArgumentString
  767. )
  768. {
  769. ULONG_PTR dwAddress;
  770. //
  771. // Figure out the address of the Pkt. This is an offset within
  772. // dfs!DfsData.
  773. //
  774. dwAddress = (GetExpression)("dfs!DfsData");
  775. if (dwAddress) {
  776. dwAddress += FIELD_OFFSET(DFS_DATA, AVdoQueue);
  777. dumplist(
  778. dwAddress,
  779. FIELD_OFFSET(DFS_VOLUME_OBJECT,VdoLinks),
  780. dumpVdo);
  781. } else {
  782. PRINTF( NO_SYMBOLS_MESSAGE );
  783. }
  784. return(TRUE);
  785. }
  786. BOOL
  787. dumpspecialtable(
  788. ULONG_PTR dwAddress)
  789. {
  790. ULONG i;
  791. SPECIAL_HASH_TABLE HashTable;
  792. if (wGetData(dwAddress,&HashTable,sizeof(SPECIAL_HASH_TABLE))) {
  793. ULONG nBuckets = HashTable.HashMask+1;
  794. PRINTF( "NodeByteCode: 0x%x\n", HashTable.NodeTypeCode);
  795. PRINTF( "NodeByteSize: 0x%x\n", HashTable.NodeByteSize);
  796. PRINTF( "Timeout: 0x%x\n", HashTable.SpcTimeout);
  797. PRINTF( "HashMask: 0x%x\n", HashTable.HashMask);
  798. if (HashTable.NodeTypeCode != DFS_NTC_SPECIAL_HASH) {
  799. PRINTF( "NodeTypeCode != DFS_NTC_SPECIAL_HASH\n");
  800. }
  801. if ((HashTable.HashMask & (HashTable.HashMask+1)) != 0) {
  802. PRINTF( "HashMask not a power of 2!\n");
  803. return (TRUE);
  804. }
  805. dwAddress += FIELD_OFFSET(SPECIAL_HASH_TABLE, HashBuckets[0]);
  806. for (i = 0; i < nBuckets; i++) {
  807. LIST_ENTRY ListEntry;
  808. if (wGetData(dwAddress,&ListEntry,sizeof(LIST_ENTRY))) {
  809. if (ListEntry.Flink) {
  810. dumplist(
  811. dwAddress,
  812. FIELD_OFFSET(DFS_SPECIAL_INFO,HashChain),
  813. dumpSpcInfo);
  814. }
  815. } else {
  816. PRINTF("Couldn't get Bucket[%d]\n", i);
  817. return (TRUE);
  818. }
  819. dwAddress += sizeof(LIST_ENTRY);
  820. }
  821. }
  822. return TRUE;
  823. }
  824. /*
  825. * specialtable : Routine to dump out the special table
  826. *
  827. */
  828. BOOL
  829. specialtable(
  830. ULONG_PTR dwCurrentPC,
  831. PWINDBG_EXTENSION_APIS lpExtensionApis,
  832. LPSTR lpArgumentString)
  833. {
  834. ULONG i;
  835. ULONG_PTR dwAddress;
  836. //
  837. // Figure out the address of the Pkt. This is an offset within
  838. // dfs!DfsData.
  839. //
  840. dwAddress = (GetExpression)("dfs!DfsData");
  841. if (dwAddress) {
  842. dwAddress += FIELD_OFFSET(DFS_DATA, SpcHashTable);
  843. if (!wGetData(dwAddress,&dwAddress,sizeof(dwAddress))) {
  844. PRINTF("Couldn't get address of SpcHashTable\n");
  845. return (TRUE);
  846. }
  847. PRINTF("SpcHashTable@0x%x\n", dwAddress);
  848. return dumpspecialtable(dwAddress);
  849. } else {
  850. PRINTF( NO_SYMBOLS_MESSAGE );
  851. }
  852. return(TRUE);
  853. }
  854. /*
  855. * specialtable : Routine to dump out the special table
  856. *
  857. */
  858. BOOL
  859. ftdfstable(
  860. ULONG_PTR dwCurrentPC,
  861. PWINDBG_EXTENSION_APIS lpExtensionApis,
  862. LPSTR lpArgumentString)
  863. {
  864. ULONG i;
  865. ULONG_PTR dwAddress;
  866. //
  867. // Figure out the address of the Pkt. This is an offset within
  868. // dfs!DfsData.
  869. //
  870. dwAddress = (GetExpression)("dfs!DfsData");
  871. if (dwAddress) {
  872. dwAddress += FIELD_OFFSET(DFS_DATA, FtDfsHashTable);
  873. if (!wGetData(dwAddress,&dwAddress,sizeof(dwAddress))) {
  874. PRINTF("Couldn't get address of FtDfsHashTable\n");
  875. return (TRUE);
  876. }
  877. PRINTF("FtDfsHashTable@0x%x\n", dwAddress);
  878. return dumpspecialtable(dwAddress);
  879. } else {
  880. PRINTF( NO_SYMBOLS_MESSAGE );
  881. }
  882. return(TRUE);
  883. }
  884. /*
  885. * sitetable : Routine to dump out the site table
  886. *
  887. */
  888. BOOL
  889. sitetable(
  890. ULONG_PTR dwCurrentPC,
  891. PWINDBG_EXTENSION_APIS lpExtensionApis,
  892. LPSTR lpArgumentString)
  893. {
  894. ULONG i;
  895. ULONG_PTR dwAddress;
  896. //
  897. // Figure out the address of the Pkt. This is an offset within
  898. // dfs!DfsData.
  899. //
  900. dwAddress = (GetExpression)("dfs!DfsData");
  901. if (dwAddress) {
  902. SITE_HASH_TABLE HashTable;
  903. dwAddress += FIELD_OFFSET(DFS_DATA, SiteHashTable);
  904. if (!wGetData(dwAddress,&dwAddress,sizeof(dwAddress))) {
  905. PRINTF("Couldn't get address of SiteHashTable\n");
  906. return (TRUE);
  907. }
  908. PRINTF("SiteHashTable@0x%x\n", dwAddress);
  909. if (wGetData(dwAddress,&HashTable,sizeof(SITE_HASH_TABLE))) {
  910. ULONG nBuckets = HashTable.HashMask+1;
  911. PRINTF( "NodeByteCode: 0x%x\n", HashTable.NodeTypeCode);
  912. PRINTF( "NodeByteSize: 0x%x\n", HashTable.NodeByteSize);
  913. PRINTF( "HashMask: 0x%x\n", HashTable.HashMask);
  914. if (HashTable.NodeTypeCode != DFS_NTC_SITE_HASH) {
  915. PRINTF( "NodeTypeCode != DFS_NTC_SITE_HASH\n");
  916. }
  917. if ((HashTable.HashMask & (HashTable.HashMask+1)) != 0) {
  918. PRINTF( "HashMask not a power of 2!\n");
  919. return (TRUE);
  920. }
  921. dwAddress += FIELD_OFFSET(SITE_HASH_TABLE, HashBuckets[0]);
  922. for (i = 0; i < nBuckets; i++) {
  923. LIST_ENTRY ListEntry;
  924. if (CheckControlC())
  925. return TRUE;
  926. if (wGetData(dwAddress,&ListEntry,sizeof(LIST_ENTRY))) {
  927. if (ListEntry.Flink) {
  928. dumplist(
  929. dwAddress,
  930. FIELD_OFFSET(DFS_SITE_INFO,HashChain),
  931. dumpSiteInfo);
  932. }
  933. } else {
  934. PRINTF("Couldn't get Bucket[%d]\n", i);
  935. return (TRUE);
  936. }
  937. dwAddress += sizeof(LIST_ENTRY);
  938. }
  939. }
  940. } else {
  941. PRINTF( NO_SYMBOLS_MESSAGE );
  942. }
  943. return(TRUE);
  944. }
  945. /*
  946. * iptable : Routine to dump out the ip table
  947. *
  948. */
  949. BOOL
  950. iptable(
  951. ULONG_PTR dwCurrentPC,
  952. PWINDBG_EXTENSION_APIS lpExtensionApis,
  953. LPSTR lpArgumentString)
  954. {
  955. ULONG i;
  956. ULONG_PTR dwAddress;
  957. //
  958. // Figure out the address of the Pkt. This is an offset within
  959. // dfs!DfsData.
  960. //
  961. dwAddress = (GetExpression)("dfs!DfsData");
  962. if (dwAddress) {
  963. IP_HASH_TABLE HashTable;
  964. dwAddress += FIELD_OFFSET(DFS_DATA, IpHashTable);
  965. if (!wGetData(dwAddress,&dwAddress,sizeof(dwAddress))) {
  966. PRINTF("Couldn't get address of IpHashTable\n");
  967. return (TRUE);
  968. }
  969. PRINTF("IpHashTable@0x%x\n", dwAddress);
  970. if (wGetData(dwAddress,&HashTable,sizeof(IP_HASH_TABLE))) {
  971. ULONG nBuckets = HashTable.HashMask+1;
  972. PRINTF( "NodeByteCode: 0x%x\n", HashTable.NodeTypeCode);
  973. PRINTF( "NodeByteSize: 0x%x\n", HashTable.NodeByteSize);
  974. PRINTF( "MaxEntries: 0x%x\n", HashTable.MaxEntries);
  975. PRINTF( "EntryCount: 0x%x\n", HashTable.EntryCount);
  976. PRINTF( "HashMask: 0x%x\n", HashTable.HashMask);
  977. if (HashTable.NodeTypeCode != DFS_NTC_IP_HASH) {
  978. PRINTF( "NodeTypeCode != DFS_NTC_IP_HASH\n");
  979. }
  980. if ((HashTable.HashMask & (HashTable.HashMask+1)) != 0) {
  981. PRINTF( "HashMask not a power of 2!\n");
  982. return (TRUE);
  983. }
  984. dwAddress += FIELD_OFFSET(IP_HASH_TABLE, HashBuckets[0]);
  985. for (i = 0; i < nBuckets; i++) {
  986. LIST_ENTRY ListEntry;
  987. if (CheckControlC())
  988. return TRUE;
  989. if (wGetData(dwAddress,&ListEntry,sizeof(LIST_ENTRY))) {
  990. if (ListEntry.Flink) {
  991. dumplist(
  992. dwAddress,
  993. FIELD_OFFSET(DFS_IP_INFO,HashChain),
  994. dumpIpInfo);
  995. }
  996. } else {
  997. PRINTF("Couldn't get Bucket[%d]\n", i);
  998. return (TRUE);
  999. }
  1000. dwAddress += sizeof(LIST_ENTRY);
  1001. }
  1002. }
  1003. } else {
  1004. PRINTF( NO_SYMBOLS_MESSAGE );
  1005. }
  1006. return(TRUE);
  1007. }
  1008. /*
  1009. * Dumpdfs : recursively dumps a DFS_PREFIX_TABLE
  1010. *
  1011. */
  1012. BOOL
  1013. dumpdfs(
  1014. ULONG_PTR dwCurrentPC,
  1015. PWINDBG_EXTENSION_APIS lpExtensionApis,
  1016. LPSTR lpArgumentString
  1017. )
  1018. {
  1019. PDFS_DATA pDfsData;
  1020. PDFS_PKT pPkt;
  1021. ULONG_PTR dwAddress;
  1022. ULONG_PTR dwPrefixTable;
  1023. if( lpArgumentString && *lpArgumentString ) {
  1024. BYTE DataBuffer[sizeof(DFS_DATA)];
  1025. pDfsData = (PDFS_DATA) DataBuffer;
  1026. dwAddress = (GetExpression)( lpArgumentString );
  1027. if (wGetData(dwAddress,pDfsData,sizeof(DFS_DATA))) {
  1028. if (pDfsData->NodeTypeCode != DSFS_NTC_DATA_HEADER) {
  1029. PRINTF( "Bad NodeTypeCode - not a DfsData struct\n");
  1030. return (FALSE);
  1031. }
  1032. PRINTF( "--DFSDATA@0x%x--\n", dwAddress);
  1033. PRINTF( "DfsData->NodeTypeCode: 0x%x\n", pDfsData->NodeTypeCode);
  1034. PRINTF( "DfsData->Pkt@0x%x\n", FIELD_OFFSET(DFS_DATA, Pkt) + dwAddress);
  1035. PRINTF( "DfsData->Pkt.NodeTypeCode: 0x%x\n", pDfsData->Pkt.NodeTypeCode);
  1036. // LocalVolTable
  1037. dwPrefixTable = dwAddress + FIELD_OFFSET(DFS_DATA, Pkt.LocalVolTable.RootEntry);
  1038. DumpDfsPrefixTableEntry(dwPrefixTable, MyDumpLocalVolEntry);
  1039. // PrefixTable
  1040. dwPrefixTable = dwAddress + FIELD_OFFSET(DFS_DATA, Pkt.PrefixTable.RootEntry);
  1041. DumpDfsPrefixTableEntry(dwPrefixTable, MyDumpPktEntry);
  1042. // PrefixTable
  1043. dwPrefixTable = dwAddress + FIELD_OFFSET(DFS_DATA, Pkt.ShortPrefixTable.RootEntry);
  1044. DumpDfsPrefixTableEntry(dwPrefixTable, MyDumpPktEntry);
  1045. } else {
  1046. PRINTF( "Error reading Memory @ %lx\n",dwAddress);
  1047. }
  1048. } else {
  1049. //
  1050. // The command is of the form
  1051. // dumpdfs addr
  1052. //
  1053. // The user didn't give us an address.
  1054. //
  1055. PRINTF(
  1056. "!dfskd.dumpDfsPrefixTable address\n"
  1057. );
  1058. }
  1059. return TRUE;
  1060. }
  1061. /*
  1062. * DumpUnicodePrefixTable : Dump a UNICODE_PREFIX_TABLE
  1063. *
  1064. */
  1065. VOID
  1066. DumpUnicodePrefixTable(ULONG_PTR dwAddress)
  1067. {
  1068. PUNICODE_PREFIX_TABLE pUnicodePrefixTable;
  1069. BYTE DataBuffer[sizeof(UNICODE_PREFIX_TABLE)];
  1070. pUnicodePrefixTable = (PUNICODE_PREFIX_TABLE) DataBuffer;
  1071. if (wGetData(dwAddress,pUnicodePrefixTable,sizeof(UNICODE_PREFIX_TABLE))) {
  1072. IPRINTF(0, "UNICODE_PREFIX_TABLE @ 0x%lx:\n", dwAddress);
  1073. IPRINTF(0, "NodeTypeCode : 0x%x\n", pUnicodePrefixTable->NodeTypeCode);
  1074. IPRINTF(0, "NextPrefixTree : 0x%lx\n", pUnicodePrefixTable->NextPrefixTree);
  1075. IPRINTF(0, "LastNextEntry : 0x%lx\n", pUnicodePrefixTable->LastNextEntry);
  1076. DumpUnicodePrefixTableEntry((ULONG_PTR)pUnicodePrefixTable->NextPrefixTree);
  1077. } else {
  1078. PRINTF( "Error reading Memory @ %lx\n",dwAddress);
  1079. }
  1080. }
  1081. /*
  1082. * DumpUnicodePrefixTableEntry : UNICODE_PREFIX_TABLE_ENTRY
  1083. *
  1084. */
  1085. VOID
  1086. DumpUnicodePrefixTableEntry(ULONG_PTR dwAddress)
  1087. {
  1088. PUNICODE_PREFIX_TABLE_ENTRY pUnicodePrefixTableEntry;
  1089. BYTE DataBuffer[sizeof(UNICODE_PREFIX_TABLE_ENTRY)];
  1090. pUnicodePrefixTableEntry = (PUNICODE_PREFIX_TABLE_ENTRY) DataBuffer;
  1091. if (wGetData(dwAddress,pUnicodePrefixTableEntry,sizeof(UNICODE_PREFIX_TABLE_ENTRY))) {
  1092. // Get and print PathSegment
  1093. if (pUnicodePrefixTableEntry->Prefix->Buffer) {
  1094. IPRINTF( "UNICODE_PREFIX_TABLE_ENTRY @ 0x%lx:\n", dwAddress);
  1095. IPRINTF( "NodeTypeCode : 0x%x\n", pUnicodePrefixTableEntry->NodeTypeCode);
  1096. IPRINTSTRINGW("", pUnicodePrefixTableEntry->Prefix, TRUE);
  1097. }
  1098. } else {
  1099. PRINTF( "Error reading Memory @ %lx\n",dwAddress);
  1100. }
  1101. }
  1102. /*
  1103. * DumpDfsPrefixTableEntry : Recursively dump a DFS_PREFIX_TABLE
  1104. *
  1105. * Prints the DFS_PREFIX_TABLE_ENTRY, then calls itself to print any siblings,
  1106. * then calls itself to print children.
  1107. *
  1108. */
  1109. VOID
  1110. DumpDfsPrefixTableEntry(ULONG_PTR dwAddress, VOID (*DumpFunc)(ULONG_PTR dwAddress))
  1111. {
  1112. PDFS_PREFIX_TABLE_ENTRY pDfsPrefixTableEntry;
  1113. BYTE DataBuffer[sizeof(DFS_PREFIX_TABLE_ENTRY)];
  1114. BOOLEAN Verbose = 0;
  1115. if (CheckControlC())
  1116. return;
  1117. pDfsPrefixTableEntry = (PDFS_PREFIX_TABLE_ENTRY) DataBuffer;
  1118. if (wGetData(dwAddress,pDfsPrefixTableEntry,sizeof(DFS_PREFIX_TABLE_ENTRY))) {
  1119. IPRINTF( "------DFS_PREFIX_TABLE_ENTRY@0x%x-----------\n", dwAddress);
  1120. IPRINTF( "pParentEntry: 0x%lx\n", pDfsPrefixTableEntry->pParentEntry);
  1121. IPRINTF( "pNextEntry: 0x%lx\n", pDfsPrefixTableEntry->pNextEntry);
  1122. IPRINTF( "pPrevEntry: 0x%lx\n", pDfsPrefixTableEntry->pPrevEntry);
  1123. IPRINTF( "pFirstChildEntry: 0x%lx\n", pDfsPrefixTableEntry->pFirstChildEntry);
  1124. IPRINTF( "pSiblingEntry: 0x%lx\n", pDfsPrefixTableEntry->pSiblingEntry);
  1125. IPRINTF( "NoOfChildren: 0x%lx\n", pDfsPrefixTableEntry->NoOfChildren);
  1126. IPRINTF( "PathSegment: %lx\n", pDfsPrefixTableEntry->PathSegment.Buffer);
  1127. IPRINTF( "pData: 0x%lx\n", pDfsPrefixTableEntry->pData);
  1128. // Get and print PathSegment
  1129. if (pDfsPrefixTableEntry->PathSegment.Buffer) {
  1130. IPRINTSTRINGW("", &pDfsPrefixTableEntry->PathSegment, FALSE);
  1131. IPRINTF( " --> 0x%x\n", pDfsPrefixTableEntry->pData);
  1132. if (pDfsPrefixTableEntry->pData) {
  1133. ULONG_PTR dwDfsPktEntry;
  1134. dwDfsPktEntry = (ULONG_PTR) pDfsPrefixTableEntry->pData;
  1135. Indent++;
  1136. DumpFunc(dwDfsPktEntry);
  1137. Indent--;
  1138. }
  1139. }
  1140. IPRINTF( "--------------------------------------------\n", dwAddress);
  1141. // recursively dump Siblings
  1142. if (pDfsPrefixTableEntry->pSiblingEntry)
  1143. DumpDfsPrefixTableEntry(
  1144. (ULONG_PTR)pDfsPrefixTableEntry->pSiblingEntry,
  1145. DumpFunc);
  1146. // then children
  1147. Indent++;
  1148. if (pDfsPrefixTableEntry->pFirstChildEntry)
  1149. DumpDfsPrefixTableEntry(
  1150. (ULONG_PTR)pDfsPrefixTableEntry->pFirstChildEntry,
  1151. DumpFunc);
  1152. Indent--;
  1153. } else {
  1154. PRINTF( "Error reading Memory @ %lx\n",dwAddress);
  1155. }
  1156. }
  1157. VOID
  1158. MyDumpPktEntry(ULONG_PTR dwAddress)
  1159. {
  1160. PDFS_PKT_ENTRY pDfsPktEntry;
  1161. BYTE DataBuffer[sizeof(DFS_PKT_ENTRY)];
  1162. // dwAddress points to PrefixTableEntry within the DFS_PKT_ENTRY struct
  1163. dwAddress -= FIELD_OFFSET(DFS_PKT_ENTRY, PrefixTableEntry);
  1164. pDfsPktEntry = (PDFS_PKT_ENTRY) DataBuffer;
  1165. if (wGetData(dwAddress,pDfsPktEntry,sizeof(DFS_PKT_ENTRY))) {
  1166. IPRINTF( "---------DFS_PKT_ENTRY@0x%x----\n", dwAddress);
  1167. IPRINTF( "NodeTypeCode: 0x%x\n", pDfsPktEntry->NodeTypeCode);
  1168. IPRINTF( "Type: 0x%x\n", pDfsPktEntry->Type);
  1169. Indent++;
  1170. IPRINTF( "----DFS_PKT_ENTRY_ID@0x%x------\n", dwAddress + FIELD_OFFSET(DFS_PKT_ENTRY, Id));
  1171. IPRINTSTRINGW("Prefix: ", &pDfsPktEntry->Id.Prefix, TRUE);
  1172. IPRINTSTRINGW("ShortPrefix:", &pDfsPktEntry->Id.Prefix, TRUE);
  1173. IPRINTF( "-------------------------------\n");
  1174. IPRINTF( "---DFS_PKT_ENTRY_INFO@0x%x-----\n", dwAddress + FIELD_OFFSET(DFS_PKT_ENTRY, Info));
  1175. IPRINTF( "Timeout\n", pDfsPktEntry->Info.Timeout);
  1176. IPRINTF( "ServiceList (%d services)\n", pDfsPktEntry->Info.ServiceCount);
  1177. Indent++;
  1178. MyDumpServices((ULONG_PTR)pDfsPktEntry->Info.ServiceList, pDfsPktEntry->Info.ServiceCount);
  1179. Indent--;
  1180. IPRINTF( "-------------------------------\n");
  1181. IPRINTF( "ActiveService:\n");
  1182. Indent++;
  1183. MyDumpServices((ULONG_PTR)pDfsPktEntry->ActiveService, 1);
  1184. Indent--;
  1185. IPRINTF( "LocalService:\n");
  1186. Indent++;
  1187. MyDumpServices((ULONG_PTR)pDfsPktEntry->LocalService, 1);
  1188. Indent--;
  1189. IPRINTF( "-------------------------------\n");
  1190. Indent--;
  1191. IPRINTF( "-------------------------------\n");
  1192. }
  1193. }
  1194. VOID
  1195. MyDumpServices(ULONG_PTR dwAddress, ULONG ServiceCount)
  1196. {
  1197. PDFS_SERVICE pDfsService;
  1198. BYTE DataBuffer[sizeof(DFS_SERVICE) * 32];
  1199. ULONG i;
  1200. pDfsService = (PDFS_SERVICE) DataBuffer;
  1201. if (wGetData(dwAddress,pDfsService,sizeof(DFS_SERVICE) * ServiceCount)) {
  1202. for (i = 0; i < ServiceCount; i++) {
  1203. if (CheckControlC())
  1204. return;
  1205. IPRINTF( "----DFS_SERVICE@0x%x---\n", dwAddress);
  1206. IPRINTSTRINGW("Service:", &pDfsService[i].Address, TRUE);
  1207. IPRINTF( "-----------------------\n");
  1208. dwAddress += sizeof(DFS_SERVICE);
  1209. }
  1210. }
  1211. }
  1212. VOID
  1213. MyDumpLocalVolEntry(ULONG_PTR dwPrefixTableEntry)
  1214. {
  1215. PDFS_LOCAL_VOL_ENTRY pDfsLocalVolEntry;
  1216. BYTE DataBuffer[sizeof(DFS_LOCAL_VOL_ENTRY)];
  1217. ULONG_PTR dwAddress;
  1218. dwAddress = dwPrefixTableEntry - FIELD_OFFSET(DFS_LOCAL_VOL_ENTRY, PrefixTableEntry);
  1219. pDfsLocalVolEntry = (PDFS_LOCAL_VOL_ENTRY) DataBuffer;
  1220. if (wGetData(dwAddress,pDfsLocalVolEntry,sizeof(DFS_LOCAL_VOL_ENTRY))) {
  1221. IPRINTF( "---------DFS_LOCAL_VOL_ENTRY@0x%x-----\n", dwAddress);
  1222. IPRINTSTRINGW("LocalPath:", &pDfsLocalVolEntry->LocalPath, TRUE);
  1223. IPRINTSTRINGW("ShareName:", &pDfsLocalVolEntry->ShareName, TRUE);
  1224. Indent++;
  1225. MyDumpPktEntry(
  1226. (ULONG_PTR) pDfsLocalVolEntry->PktEntry +
  1227. FIELD_OFFSET(DFS_PKT_ENTRY, PrefixTableEntry)
  1228. );
  1229. Indent--;
  1230. IPRINTF( "--------------------------------------\n", dwAddress);
  1231. }
  1232. }
  1233. /*
  1234. * dumpVdo : Routine suitable as argument to dumplist; used to dump list of
  1235. * Vdos
  1236. */
  1237. void dumpVdo(
  1238. ULONG_PTR dwAddress
  1239. )
  1240. {
  1241. DFS_VOLUME_OBJECT dfsVdo;
  1242. if (wGetData( dwAddress, &dfsVdo, sizeof(dfsVdo) )) {
  1243. PRINTF( "\nVDO @ %08lx\n", dwAddress);
  1244. PrintStructFields( dwAddress, &dfsVdo, DfsVolumeObjectFields );
  1245. } else {
  1246. PRINTF( "\nUnable to read VDO @%08lx\n", dwAddress);
  1247. }
  1248. }
  1249. /*
  1250. * dumpSpcInfo : Routine suitable as argument to dumplist; used to dump list of
  1251. * DFS_SPECIAL_INFO's
  1252. */
  1253. void dumpSpcInfo(
  1254. ULONG_PTR dwAddress
  1255. )
  1256. {
  1257. ULONG_PTR dwName;
  1258. DFS_SPECIAL_INFO dfsSpcInfo;
  1259. LONG i;
  1260. UNICODE_STRING uStr;
  1261. if (wGetData( dwAddress, &dfsSpcInfo, sizeof(dfsSpcInfo) )) {
  1262. PRINTF( " DFS_SPECIAL_INFO @ %08lx\n", dwAddress);
  1263. PRINTF( "\tExpireTime: 0x%08x:0x%08x\n",
  1264. dfsSpcInfo.ExpireTime.HighPart,
  1265. dfsSpcInfo.ExpireTime.LowPart);
  1266. PRINTF( "\tFlags: 0x%08x\n", dfsSpcInfo.Flags, TRUE);
  1267. PRINTF( "\tTrustDirection: 0x%08x\n", dfsSpcInfo.TrustDirection, TRUE);
  1268. PRINTF( "\tTrustType: 0x%08x\n", dfsSpcInfo.TrustType, TRUE);
  1269. PRINTF( "\tTypeFlags: 0x%08x\n", dfsSpcInfo.TypeFlags, TRUE);
  1270. PRINTF( "\tNameCount: %d\n", dfsSpcInfo.NameCount, TRUE);
  1271. wPrintStringW("\tSpecialName:", &dfsSpcInfo.SpecialName, TRUE);
  1272. dwName = dwAddress + FIELD_OFFSET(DFS_SPECIAL_INFO, Name[0]);
  1273. for (i = 0; i < dfsSpcInfo.NameCount; i++) {
  1274. if (CheckControlC())
  1275. return;
  1276. wGetData(dwName, &uStr, sizeof(UNICODE_STRING));
  1277. wPrintStringW("\t\tName:", &uStr, TRUE);
  1278. dwName += sizeof(UNICODE_STRING);
  1279. }
  1280. } else {
  1281. PRINTF( "Unable to read DFS_SITE_INFO @%08lx\n", dwAddress);
  1282. }
  1283. }
  1284. /*
  1285. * dumpSiteInfo : Routine suitable as argument to dumplist; used to dump list of
  1286. * DFS_SITE_INFO's
  1287. */
  1288. void dumpSiteInfo(
  1289. ULONG_PTR dwAddress
  1290. )
  1291. {
  1292. ULONG_PTR dwSiteName;
  1293. DFS_SITE_INFO dfsSiteInfo;
  1294. ULONG i;
  1295. UNICODE_STRING uStr;
  1296. if (wGetData( dwAddress, &dfsSiteInfo, sizeof(dfsSiteInfo) )) {
  1297. PRINTF( " DFS_SITE_INFO @ %08lx\n", dwAddress);
  1298. wPrintStringW("\tServerName:", &dfsSiteInfo.ServerName, TRUE);
  1299. dwSiteName = dwAddress + FIELD_OFFSET(DFS_SITE_INFO, SiteName[0]);
  1300. for (i = 0; i < dfsSiteInfo.SiteCount; i++) {
  1301. wGetData(dwSiteName, &uStr, sizeof(UNICODE_STRING));
  1302. wPrintStringW("\t\tName:", &uStr, TRUE);
  1303. dwSiteName += sizeof(UNICODE_STRING);
  1304. }
  1305. } else {
  1306. PRINTF( "Unable to read DFS_SITE_INFO @%08lx\n", dwAddress);
  1307. }
  1308. }
  1309. /*
  1310. * dumpIpInfo : Routine suitable as argument to dumplist; used to dump list of
  1311. * DFS_IP_INFO's
  1312. */
  1313. void dumpIpInfo(
  1314. ULONG_PTR dwAddress
  1315. )
  1316. {
  1317. DFS_IP_INFO dfsIpInfo;
  1318. ULONG IpAddress;
  1319. if (wGetData( dwAddress, &dfsIpInfo, sizeof(dfsIpInfo) )) {
  1320. IpAddress = *((ULONG *)&dfsIpInfo.IpAddress.IpData);
  1321. PRINTF( " DFS_IP_INFO @ %08lx\n", dwAddress);
  1322. PRINTF( "\tIpAddress: %d.%d.%d.%d\n",
  1323. IpAddress & 0xff,
  1324. (IpAddress >> 8) & 0xff,
  1325. (IpAddress >> 16) & 0xff,
  1326. (IpAddress >> 24) & 0xff);
  1327. wPrintStringW("\tSiteName: ", &dfsIpInfo.SiteName, TRUE);
  1328. } else {
  1329. PRINTF( "Unable to read DFS_SITE_INFO @%08lx\n", dwAddress);
  1330. }
  1331. }
  1332. /*
  1333. * dumplist : A general-purpose routine to dump a list of structures
  1334. *
  1335. */
  1336. VOID
  1337. dumplist(
  1338. ULONG_PTR dwListEntryAddress,
  1339. DWORD linkOffset,
  1340. VOID (*dumpRoutine)(ULONG_PTR dwStructAddress)
  1341. )
  1342. {
  1343. LIST_ENTRY listHead, listNext;
  1344. ULONG max_list_entry = MAX_ENTRIES;
  1345. //
  1346. // Get the value in the LIST_ENTRY at dwAddress
  1347. //
  1348. PRINTF( "Dumping list @ %08lx\n", dwListEntryAddress );
  1349. if (wGetData(dwListEntryAddress, &listHead, sizeof(LIST_ENTRY))) {
  1350. ULONG_PTR dwNextLink = (ULONG_PTR) listHead.Flink;
  1351. ULONG_PTR dwNextdupLink = (ULONG_PTR) listHead.Flink;
  1352. ULONG loop_count = 0;
  1353. if (dwNextLink == 0) {
  1354. PRINTF( "Uninitialized list!\n" );
  1355. } else if (dwNextLink == dwListEntryAddress) {
  1356. PRINTF( "Empty list!\n" );
  1357. } else {
  1358. while( dwNextLink != dwListEntryAddress) {
  1359. ULONG_PTR dwStructAddress;
  1360. if (CheckControlC())
  1361. return;
  1362. dwStructAddress = dwNextLink - linkOffset;
  1363. dumpRoutine(dwStructAddress);
  1364. if (wGetData( dwNextLink, &listNext, sizeof(LIST_ENTRY))) {
  1365. dwNextLink = (ULONG_PTR) listNext.Flink;
  1366. } else {
  1367. PRINTF( "Unable to get next item @%08lx\n", dwNextLink );
  1368. break;
  1369. }
  1370. if (++loop_count > max_list_entry) {
  1371. PRINTF( "Dumped maximum %d entries... aborting\n", loop_count);
  1372. break;
  1373. }
  1374. }
  1375. }
  1376. } else {
  1377. PRINTF( "Unable to read list head @ %08lx\n", dwListEntryAddress);
  1378. }
  1379. }
  1380. VOID
  1381. DoIndent(VOID)
  1382. {
  1383. INT i;
  1384. for (i = 0; i < 2 * Indent; i++)
  1385. PRINTF(" ");
  1386. }
  1387. VOID
  1388. PrintStructFields( ULONG_PTR dwAddress, VOID *ptr, FIELD_DESCRIPTOR *pFieldDescriptors )
  1389. {
  1390. int i;
  1391. WCHAR wszBuffer[80];
  1392. // Display the fields in the struct.
  1393. for( i=0; pFieldDescriptors->Name; i++, pFieldDescriptors++ ) {
  1394. // Indentation to begin the struct display.
  1395. PRINTF( " " );
  1396. if( strlen( pFieldDescriptors->Name ) > FIELD_NAME_LENGTH ) {
  1397. PRINTF( "%-17s...%s ", pFieldDescriptors->Name, pFieldDescriptors->Name+strlen(pFieldDescriptors->Name)-10 );
  1398. } else {
  1399. PRINTF( "%-30s ", pFieldDescriptors->Name );
  1400. }
  1401. switch( pFieldDescriptors->FieldType ) {
  1402. case FieldTypeByte:
  1403. case FieldTypeChar:
  1404. PRINTF( "%-16d%s",
  1405. *(BYTE *)(((char *)ptr) + pFieldDescriptors->Offset ),
  1406. NewLineForFields(i) );
  1407. break;
  1408. case FieldTypeBoolean:
  1409. PRINTF( "%-16s%s",
  1410. *(BOOLEAN *)(((char *)ptr) + pFieldDescriptors->Offset ) ? "TRUE" : "FALSE",
  1411. NewLineForFields(i));
  1412. break;
  1413. case FieldTypeBool:
  1414. PRINTF( "%-16s%s",
  1415. *(BOOLEAN *)(((char *)ptr) + pFieldDescriptors->Offset ) ? "TRUE" : "FALSE",
  1416. NewLineForFields(i));
  1417. break;
  1418. case FieldTypePointer:
  1419. PRINTF( "%-16X%s",
  1420. *(ULONG *)(((char *)ptr) + pFieldDescriptors->Offset ),
  1421. NewLineForFields(i) );
  1422. break;
  1423. case FieldTypeULong:
  1424. case FieldTypeLong:
  1425. PRINTF( "%-16d%s",
  1426. *(ULONG *)(((char *)ptr) + pFieldDescriptors->Offset ),
  1427. NewLineForFields(i) );
  1428. break;
  1429. case FieldTypeShort:
  1430. PRINTF( "%-16X%s",
  1431. *(SHORT *)(((char *)ptr) + pFieldDescriptors->Offset ),
  1432. NewLineForFields(i) );
  1433. break;
  1434. case FieldTypeUShort:
  1435. PRINTF( "%-16X%s",
  1436. *(USHORT *)(((char *)ptr) + pFieldDescriptors->Offset ),
  1437. NewLineForFields(i) );
  1438. break;
  1439. case FieldTypeGuid:
  1440. PrintGuid( (GUID *)(((char *)ptr) + pFieldDescriptors->Offset) );
  1441. PRINTF( NewLine );
  1442. break;
  1443. case FieldTypePWStr:
  1444. if (wGetString( (ULONG_PTR)(((char *)ptr) + pFieldDescriptors->Offset), (char *)wszBuffer )) {
  1445. PRINTF( "%ws", wszBuffer );
  1446. } else {
  1447. PRINTF( "Unable to get string at %08lx", (ULONG_PTR)(((char *)ptr) + pFieldDescriptors->Offset));
  1448. }
  1449. PRINTF( NewLine );
  1450. break;
  1451. case FieldTypeUnicodeString:
  1452. wPrintStringW( NULL, (UNICODE_STRING *)(((char *)ptr) + pFieldDescriptors->Offset ), 0 );
  1453. PRINTF( NewLine );
  1454. break;
  1455. case FieldTypeAnsiString:
  1456. wPrintStringA( NULL, (ANSI_STRING *)(((char *)ptr) + pFieldDescriptors->Offset ), 0 );
  1457. PRINTF( NewLine );
  1458. break;
  1459. case FieldTypeSymbol:
  1460. {
  1461. UCHAR SymbolName[ 200 ];
  1462. ULONG Displacement;
  1463. PVOID sym = (PVOID)(*(ULONG_PTR *)(((char *)ptr) + pFieldDescriptors->Offset ));
  1464. GetSymbol(sym, SymbolName, (ULONG_PTR *)&Displacement );
  1465. PRINTF( "%-16s%s",
  1466. SymbolName,
  1467. NewLineForFields(i) );
  1468. }
  1469. break;
  1470. case FieldTypeEnum:
  1471. {
  1472. ULONG EnumValue;
  1473. ENUM_VALUE_DESCRIPTOR *pEnumValueDescr;
  1474. // Get the associated numerical value.
  1475. EnumValue = *((ULONG *)((BYTE *)ptr + pFieldDescriptors->Offset));
  1476. if ((pEnumValueDescr = pFieldDescriptors->AuxillaryInfo.pEnumValueDescriptor)
  1477. != NULL) {
  1478. //
  1479. // An auxilary textual description of the value is
  1480. // available. Display it instead of the numerical value.
  1481. //
  1482. LPSTR pEnumName = NULL;
  1483. while (pEnumValueDescr->EnumName != NULL) {
  1484. if (EnumValue == pEnumValueDescr->EnumValue) {
  1485. pEnumName = pEnumValueDescr->EnumName;
  1486. break;
  1487. }
  1488. pEnumValueDescr++;
  1489. }
  1490. if (pEnumName != NULL) {
  1491. PRINTF( "%-16s ", pEnumName );
  1492. } else {
  1493. PRINTF( "%-4d (%-10s) ", EnumValue,"Unknown!");
  1494. }
  1495. } else {
  1496. //
  1497. // No auxilary information is associated with the ehumerated type
  1498. // print the numerical value.
  1499. //
  1500. PRINTF( "%-16d",EnumValue);
  1501. }
  1502. PRINTF( NewLineForFields(i) );
  1503. }
  1504. break;
  1505. case FieldTypeByteBitMask:
  1506. case FieldTypeWordBitMask:
  1507. case FieldTypeDWordBitMask:
  1508. {
  1509. BOOL fFirstFlag;
  1510. ULONG BitMaskValue;
  1511. BIT_MASK_DESCRIPTOR *pBitMaskDescr;
  1512. BitMaskValue = *((ULONG *)((BYTE *)ptr + pFieldDescriptors->Offset));
  1513. PRINTF("%-8x ", BitMaskValue);
  1514. PRINTF( NewLineForFields(i) );
  1515. pBitMaskDescr = pFieldDescriptors->AuxillaryInfo.pBitMaskDescriptor;
  1516. fFirstFlag = TRUE;
  1517. if (BitMaskValue != 0 && pBitMaskDescr != NULL) {
  1518. while (pBitMaskDescr->BitmaskName != NULL) {
  1519. if ((BitMaskValue & pBitMaskDescr->BitmaskValue) != 0) {
  1520. if (fFirstFlag) {
  1521. fFirstFlag = FALSE;
  1522. PRINTF(" ( %-s", pBitMaskDescr->BitmaskName);
  1523. } else {
  1524. PRINTF( " |\n" );
  1525. PRINTF(" %-s", pBitMaskDescr->BitmaskName);
  1526. }
  1527. }
  1528. pBitMaskDescr++;
  1529. }
  1530. PRINTF(" )");
  1531. PRINTF( NewLineForFields(i) );
  1532. }
  1533. }
  1534. break;
  1535. case FieldTypeStruct:
  1536. PRINTF( "@%-15X%s",
  1537. (dwAddress + pFieldDescriptors->Offset ),
  1538. NewLineForFields(i) );
  1539. break;
  1540. case FieldTypeLargeInteger:
  1541. wPrintLargeInt( (LARGE_INTEGER *)(((char *)ptr) + pFieldDescriptors->Offset) );
  1542. PRINTF( NewLine );
  1543. break;
  1544. case FieldTypeFileTime:
  1545. default:
  1546. dprintf( "Unrecognized field type %c for %s\n", pFieldDescriptors->FieldType, pFieldDescriptors->Name );
  1547. break;
  1548. }
  1549. }
  1550. }
  1551. #define NAME_DELIMITER '@'
  1552. #define INVALID_INDEX 0xffffffff
  1553. #define MIN(x,y) ((x) < (y) ? (x) : (y))
  1554. ULONG SearchStructs(LPSTR lpArgument)
  1555. {
  1556. ULONG i = 0;
  1557. STRUCT_DESCRIPTOR *pStructs = Structs;
  1558. ULONG NameIndex = INVALID_INDEX;
  1559. ULONG ArgumentLength = strlen(lpArgument);
  1560. BOOLEAN fAmbiguous = FALSE;
  1561. while ((pStructs->StructName != 0)) {
  1562. ULONG StructLength;
  1563. StructLength = strlen(pStructs->StructName);
  1564. if (StructLength >= ArgumentLength) {
  1565. int Result = _strnicmp(
  1566. lpArgument,
  1567. pStructs->StructName,
  1568. ArgumentLength);
  1569. if (Result == 0) {
  1570. if (StructLength == ArgumentLength) {
  1571. // Exact match. They must mean this struct!
  1572. fAmbiguous = FALSE;
  1573. NameIndex = i;
  1574. break;
  1575. } else if (NameIndex != INVALID_INDEX) {
  1576. // We have encountered duplicate matches. Print out the
  1577. // matching strings and let the user disambiguate.
  1578. fAmbiguous = TRUE;
  1579. break;
  1580. } else {
  1581. NameIndex = i;
  1582. }
  1583. }
  1584. }
  1585. pStructs++;i++;
  1586. }
  1587. if (fAmbiguous) {
  1588. PRINTF("Ambigous Name Specification -- The following structs match\n");
  1589. PRINTF("%s\n",Structs[NameIndex].StructName);
  1590. PRINTF("%s\n",Structs[i].StructName);
  1591. while (pStructs->StructName != 0) {
  1592. if (_strnicmp(lpArgument,
  1593. pStructs->StructName,
  1594. MIN(strlen(pStructs->StructName),ArgumentLength)) == 0) {
  1595. PRINTF("%s\n",pStructs->StructName);
  1596. }
  1597. pStructs++;
  1598. }
  1599. PRINTF("Dumping Information for %s\n",Structs[NameIndex].StructName);
  1600. }
  1601. return(NameIndex);
  1602. }
  1603. VOID DisplayStructs()
  1604. {
  1605. STRUCT_DESCRIPTOR *pStructs = Structs;
  1606. PRINTF("The following structs are handled .... \n");
  1607. while (pStructs->StructName != 0) {
  1608. PRINTF("\t%s\n",pStructs->StructName);
  1609. pStructs++;
  1610. }
  1611. }
  1612. #define NAME_DELIMITERS "@"
  1613. DECLARE_API( dump )
  1614. {
  1615. ULONG_PTR dwAddress;
  1616. //SETCALLBACKS();
  1617. if( args && *args ) {
  1618. // Parse the argument string to determine the structure to be displayed.
  1619. // Scan for the NAME_DELIMITER ( '@' ).
  1620. LPSTR lpName = (PSTR)args;
  1621. LPSTR lpArgs = strpbrk(args, NAME_DELIMITERS);
  1622. ULONG Index;
  1623. if (lpArgs) {
  1624. //
  1625. // The specified command is of the form
  1626. // dump <name>@<address expr.>
  1627. //
  1628. // Locate the matching struct for the given name. In the case
  1629. // of ambiguity we seek user intervention for disambiguation.
  1630. //
  1631. // We do an inplace modification of the argument string to
  1632. // facilitate matching.
  1633. //
  1634. *lpArgs = '\0';
  1635. for (;*lpName==' ';) { lpName++; } //skip leading blanks
  1636. Index = SearchStructs(lpName);
  1637. //
  1638. // Let us restore the original value back.
  1639. //
  1640. *lpArgs = NAME_DELIMITER;
  1641. if (INVALID_INDEX != Index) {
  1642. BYTE DataBuffer[512];
  1643. dwAddress = GetExpression( ++lpArgs );
  1644. if (wGetData(dwAddress,DataBuffer,Structs[Index].StructSize)) {
  1645. PRINTF(
  1646. "++++++++++++++++ %s@%lx ++++++++++++++++\n",
  1647. Structs[Index].StructName,
  1648. dwAddress);
  1649. PrintStructFields(
  1650. dwAddress,
  1651. &DataBuffer,
  1652. Structs[Index].FieldDescriptors);
  1653. PRINTF(
  1654. "---------------- %s@%lx ----------------\n",
  1655. Structs[Index].StructName,
  1656. dwAddress);
  1657. } else {
  1658. PRINTF("Error reading Memory @ %lx\n",dwAddress);
  1659. }
  1660. } else {
  1661. // No matching struct was found. Display the list of
  1662. // structs currently handled.
  1663. DisplayStructs();
  1664. }
  1665. } else {
  1666. //
  1667. // The command is of the form
  1668. // dump <name>
  1669. //
  1670. // Currently we do not handle this. In future we will map it to
  1671. // the name of a global variable and display it if required.
  1672. //
  1673. DisplayStructs();
  1674. }
  1675. } else {
  1676. //
  1677. // display the list of structs currently handled.
  1678. //
  1679. DisplayStructs();
  1680. }
  1681. return;
  1682. }