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.

426 lines
12 KiB

  1. //--------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1999, Microsoft Corporation
  4. //
  5. // File: info.cxx
  6. //
  7. //--------------------------------------------------------------------------
  8. #define UNICODE 1
  9. #include <stdio.h>
  10. #include <nt.h>
  11. #include <ntrtl.h>
  12. #include <nturtl.h>
  13. #include <windows.h>
  14. #include <shellapi.h>
  15. #include <winldap.h>
  16. #include <stdlib.h>
  17. #include <dsgetdc.h>
  18. #include <lm.h>
  19. #include <dfsstr.h>
  20. #include <dfsmrshl.h>
  21. #include <marshal.hxx>
  22. #include <lmdfs.h>
  23. #include <dfspriv.h>
  24. #include <dfsm.hxx>
  25. #include <recon.hxx>
  26. #include <rpc.h>
  27. #include "struct.hxx"
  28. #include "ftsup.hxx"
  29. #include "stdsup.hxx"
  30. #include "rootsup.hxx"
  31. #include "misc.hxx"
  32. #define OFFSET_TO_POINTER(f,b) \
  33. ((VOID *)((PCHAR)(f) + (ULONG_PTR)(b)))
  34. CHAR *OutBuf = NULL;
  35. ULONG OutBufSize = 0x1000;
  36. HANDLE DriverHandle = NULL;
  37. CHAR InBuf[0x1000];
  38. CHAR OutBuf2[0x1000];
  39. VOID
  40. GetDCs(
  41. LPWSTR Name);
  42. DWORD
  43. PktInfo(
  44. BOOLEAN fSwDfs,
  45. LPWSTR pwszHexValue)
  46. {
  47. DWORD dwErr = ERROR_SUCCESS;
  48. NTSTATUS NtStatus;
  49. IO_STATUS_BLOCK IoStatusBlock;
  50. OBJECT_ATTRIBUTES objectAttributes;
  51. UNICODE_STRING DfsDriverName;
  52. ULONG Type;
  53. ULONG State;
  54. ULONG Entry;
  55. ULONG Service;
  56. ULONG Level = 0;
  57. PDFS_GET_PKT_ARG pGetPkt = NULL;
  58. OutBuf = (PCHAR) malloc(OutBufSize);
  59. if (OutBuf == NULL) {
  60. dwErr = ERROR_OUTOFMEMORY;
  61. goto Cleanup;
  62. }
  63. if (fSwDfs == TRUE) {
  64. MyPrintf(L"--dfs.sys--\r\n");
  65. RtlInitUnicodeString(&DfsDriverName, DFS_SERVER_NAME);
  66. } else {
  67. MyPrintf(L"--mup.sys--\r\n");
  68. RtlInitUnicodeString(&DfsDriverName, DFS_DRIVER_NAME);
  69. }
  70. if (pwszHexValue != NULL) {
  71. Level = AtoHex(pwszHexValue, &dwErr);
  72. if (dwErr != ERROR_SUCCESS) {
  73. MyPrintf(L"Bad Level %ws\r\n", pwszHexValue);
  74. goto Cleanup;
  75. }
  76. }
  77. InitializeObjectAttributes(
  78. &objectAttributes,
  79. &DfsDriverName,
  80. OBJ_CASE_INSENSITIVE,
  81. NULL,
  82. NULL);
  83. NtStatus = NtCreateFile(
  84. &DriverHandle,
  85. SYNCHRONIZE,
  86. &objectAttributes,
  87. &IoStatusBlock,
  88. NULL,
  89. FILE_ATTRIBUTE_NORMAL,
  90. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  91. FILE_OPEN_IF,
  92. FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
  93. NULL,
  94. 0);
  95. if (!NT_SUCCESS(NtStatus)) {
  96. dwErr = RtlNtStatusToDosError(NtStatus);
  97. if (fSwDebug)
  98. MyPrintf(L"NtCreateFile returned 0x%x\r\n", NtStatus);
  99. goto Cleanup;
  100. }
  101. TryAgain:
  102. NtStatus = NtFsControlFile(
  103. DriverHandle,
  104. NULL, // Event,
  105. NULL, // ApcRoutine,
  106. NULL, // ApcContext,
  107. &IoStatusBlock,
  108. FSCTL_DFS_GET_PKT,
  109. NULL,
  110. 0,
  111. OutBuf,
  112. OutBufSize);
  113. if (NtStatus == STATUS_BUFFER_OVERFLOW) {
  114. OutBufSize = *((ULONG *)OutBuf);
  115. free(OutBuf);
  116. OutBuf = (PCHAR) malloc(OutBufSize);
  117. if (OutBuf == NULL) {
  118. dwErr = ERROR_OUTOFMEMORY;
  119. goto Cleanup;
  120. }
  121. goto TryAgain;
  122. }
  123. dwErr = RtlNtStatusToDosError(NtStatus);
  124. if (!NT_SUCCESS(NtStatus))
  125. goto Cleanup;
  126. pGetPkt = (PDFS_GET_PKT_ARG)OutBuf;
  127. MyPrintf(L"%d entries...\r\n", pGetPkt->EntryCount);
  128. for (Entry = 0; Entry < pGetPkt->EntryCount; Entry++) {
  129. pGetPkt->EntryObject[Entry].Prefix = (LPWSTR) OFFSET_TO_POINTER(
  130. pGetPkt->EntryObject[Entry].Prefix,
  131. OutBuf);
  132. pGetPkt->EntryObject[Entry].ShortPrefix = (LPWSTR) OFFSET_TO_POINTER(
  133. pGetPkt->EntryObject[Entry].ShortPrefix,
  134. OutBuf);
  135. pGetPkt->EntryObject[Entry].Address = (PDFS_PKT_ADDRESS_OBJECT *) OFFSET_TO_POINTER(
  136. pGetPkt->EntryObject[Entry].Address,
  137. OutBuf);
  138. for (Service = 0; Service < pGetPkt->EntryObject[Entry].ServiceCount; Service++) {
  139. pGetPkt->EntryObject[Entry].Address[Service] = (PDFS_PKT_ADDRESS_OBJECT)
  140. OFFSET_TO_POINTER(
  141. pGetPkt->EntryObject[Entry].Address[Service],
  142. OutBuf);
  143. }
  144. }
  145. for (Entry = 0; Entry < pGetPkt->EntryCount; Entry++) {
  146. MyPrintf(L"Entry: %ws\r\n", pGetPkt->EntryObject[Entry].Prefix);
  147. MyPrintf(L"ShortEntry: %ws\r\n", pGetPkt->EntryObject[Entry].ShortPrefix);
  148. MyPrintf(L"Expires in %d seconds\r\n", pGetPkt->EntryObject[Entry].ExpireTime);
  149. MyPrintf(L"UseCount: %d Type:0x%x (",
  150. pGetPkt->EntryObject[Entry].UseCount,
  151. pGetPkt->EntryObject[Entry].Type);
  152. Type = pGetPkt->EntryObject[Entry].Type;
  153. if (Type & PKT_ENTRY_TYPE_OFFLINE)
  154. MyPrintf(L" OFFLINE");
  155. if (Type & PKT_ENTRY_TYPE_LOCAL)
  156. MyPrintf(L" LOCAL");
  157. if (Type & PKT_ENTRY_TYPE_STALE)
  158. MyPrintf(L" STALE");
  159. if (Type & PKT_ENTRY_TYPE_LOCAL_XPOINT)
  160. MyPrintf(L" LOCAL_XPOINT");
  161. if (Type & PKT_ENTRY_TYPE_DELETE_PENDING)
  162. MyPrintf(L" DELETE_PENDING");
  163. if (Type & PKT_ENTRY_TYPE_PERMANENT)
  164. MyPrintf(L" PERMANENT");
  165. if (Type & PKT_ENTRY_TYPE_REFERRAL_SVC)
  166. MyPrintf(L" REFERRAL_SVC");
  167. if (Type & PKT_ENTRY_TYPE_SYSVOL)
  168. MyPrintf(L" SYSVOL");
  169. if (Type & PKT_ENTRY_TYPE_OUTSIDE_MY_DOM)
  170. MyPrintf(L" OUTSIDE_MY_DOM");
  171. if (Type & PKT_ENTRY_TYPE_LEAFONLY)
  172. MyPrintf(L" LEAFONLY");
  173. if (Type & PKT_ENTRY_TYPE_NONDFS)
  174. MyPrintf(L" NONDFS");
  175. if (Type & PKT_ENTRY_TYPE_MACHINE)
  176. MyPrintf(L" MACHINE");
  177. if (Type & PKT_ENTRY_TYPE_DFS)
  178. MyPrintf(L" DFS");
  179. if (Type & PKT_ENTRY_TYPE_INSITE_ONLY)
  180. MyPrintf(L" INSITE");
  181. MyPrintf(L" )\r\n");
  182. for (Service = 0; Service < pGetPkt->EntryObject[Entry].ServiceCount; Service++) {
  183. MyPrintf(L"%4d:[%ws] State:0x%02x ",
  184. Service,
  185. pGetPkt->EntryObject[Entry].Address[Service]->ServerShare,
  186. pGetPkt->EntryObject[Entry].Address[Service]->State);
  187. State = pGetPkt->EntryObject[Entry].Address[Service]->State;
  188. //
  189. // Ugly - used to have State == 0x1 mean 'active'. Now we return an
  190. // ULONG with multiple bits set, so 0x1 indicates the old way and
  191. // more than 1 bit set means the new way.
  192. //
  193. if (State == 0x0) {
  194. MyPrintf(L"\r\n");
  195. } else if (State == 0x1) {
  196. MyPrintf(L"( ACTIVE )\r\n");
  197. } else {
  198. MyPrintf(L"(");
  199. if (State & DFS_SERVICE_TYPE_ACTIVE)
  200. MyPrintf(L" ACTIVE");
  201. if (State & DFS_SERVICE_TYPE_OFFLINE)
  202. MyPrintf(L" OFFLINE");
  203. if (Level >= 1) {
  204. if (State & DFS_SERVICE_TYPE_MASTER)
  205. MyPrintf(L" MASTER");
  206. if (State & DFS_SERVICE_TYPE_READONLY)
  207. MyPrintf(L" READONLY");
  208. if (State & DFS_SERVICE_TYPE_LOCAL)
  209. MyPrintf(L" LOCAL");
  210. if (State & DFS_SERVICE_TYPE_REFERRAL)
  211. MyPrintf(L" REFERRAL");
  212. if (State & DFS_SERVICE_TYPE_DOWN_LEVEL)
  213. MyPrintf(L" DOWNLEVEL");
  214. if (State & DFS_SERVICE_TYPE_COSTLIER)
  215. MyPrintf(L" COSTLIER");
  216. }
  217. MyPrintf(L" )\r\n");
  218. }
  219. }
  220. MyPrintf(L"\r\n");
  221. }
  222. Cleanup:
  223. if (OutBuf != NULL) {
  224. free(OutBuf);
  225. OutBuf = NULL;
  226. }
  227. if (DriverHandle != NULL) {
  228. NTSTATUS st;
  229. st = NtClose(DriverHandle);
  230. DriverHandle = NULL;
  231. }
  232. return dwErr;
  233. }
  234. DWORD
  235. SpcInfo(
  236. BOOLEAN fSwAll)
  237. {
  238. DWORD dwErr = ERROR_SUCCESS;
  239. NTSTATUS NtStatus;
  240. IO_STATUS_BLOCK IoStatusBlock;
  241. OBJECT_ATTRIBUTES objectAttributes;
  242. UNICODE_STRING DfsDriverName;
  243. WCHAR *wCp;
  244. OutBuf = (PCHAR) malloc(OutBufSize);
  245. if (OutBuf == NULL) {
  246. dwErr = ERROR_OUTOFMEMORY;
  247. goto Cleanup;
  248. }
  249. RtlInitUnicodeString(&DfsDriverName, DFS_DRIVER_NAME);
  250. InitializeObjectAttributes(
  251. &objectAttributes,
  252. &DfsDriverName,
  253. OBJ_CASE_INSENSITIVE,
  254. NULL,
  255. NULL);
  256. NtStatus = NtCreateFile(
  257. &DriverHandle,
  258. SYNCHRONIZE,
  259. &objectAttributes,
  260. &IoStatusBlock,
  261. NULL,
  262. FILE_ATTRIBUTE_NORMAL,
  263. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  264. FILE_OPEN_IF,
  265. FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
  266. NULL,
  267. 0);
  268. if (!NT_SUCCESS(NtStatus)) {
  269. dwErr = RtlNtStatusToDosError(NtStatus);
  270. if (fSwDebug)
  271. MyPrintf(L"NtCreateFile returned 0x%x\r\n", NtStatus);
  272. goto Cleanup;
  273. }
  274. TryAgain:
  275. wcscpy((WCHAR *)InBuf, L"*");
  276. NtStatus = NtFsControlFile(
  277. DriverHandle,
  278. NULL, // Event,
  279. NULL, // ApcRoutine,
  280. NULL, // ApcContext,
  281. &IoStatusBlock,
  282. FSCTL_DFS_GET_SPC_TABLE,
  283. InBuf,
  284. sizeof(InBuf),
  285. OutBuf,
  286. OutBufSize);
  287. if (NtStatus == STATUS_BUFFER_OVERFLOW) {
  288. OutBufSize = *((ULONG *)OutBuf);
  289. free(OutBuf);
  290. OutBuf = (PCHAR)malloc(OutBufSize);
  291. if (OutBuf == NULL) {
  292. dwErr = ERROR_OUTOFMEMORY;
  293. goto Cleanup;
  294. }
  295. goto TryAgain;
  296. }
  297. dwErr = RtlNtStatusToDosError(NtStatus);
  298. if (NtStatus == STATUS_SUCCESS) {
  299. wCp = (WCHAR *)OutBuf;
  300. while (*wCp) {
  301. MyPrintf(L"[%c][%ws]\r\n", *wCp, (wCp+1));
  302. wCp += wcslen(wCp) + 1;
  303. }
  304. }
  305. wcscpy((WCHAR *)InBuf, L"");
  306. NtStatus = NtFsControlFile(
  307. DriverHandle,
  308. NULL, // Event,
  309. NULL, // ApcRoutine,
  310. NULL, // ApcContext,
  311. &IoStatusBlock,
  312. FSCTL_DFS_GET_SPC_TABLE,
  313. InBuf,
  314. sizeof(InBuf),
  315. OutBuf,
  316. OutBufSize);
  317. if (NtStatus == STATUS_BUFFER_OVERFLOW) {
  318. OutBufSize = *((ULONG *)OutBuf);
  319. OutBuf = (PCHAR)malloc(OutBufSize);
  320. if (OutBuf == NULL) {
  321. dwErr = ERROR_OUTOFMEMORY;
  322. goto Cleanup;
  323. }
  324. goto TryAgain;
  325. }
  326. dwErr = RtlNtStatusToDosError(NtStatus);
  327. if (NtStatus == STATUS_SUCCESS) {
  328. wCp = (WCHAR *)OutBuf;
  329. while (*wCp) {
  330. MyPrintf(L"[%c][%ws]\r\n", *wCp, (wCp+1));
  331. if (fSwAll == TRUE || *wCp == '+') {
  332. GetDCs((wCp+1));
  333. }
  334. wCp += wcslen(wCp) + 1;
  335. }
  336. }
  337. Cleanup:
  338. if (DriverHandle != NULL) {
  339. NtClose(DriverHandle);
  340. DriverHandle = NULL;
  341. }
  342. if (OutBuf != NULL) {
  343. free(OutBuf);
  344. OutBuf = NULL;
  345. }
  346. return dwErr;
  347. }
  348. VOID
  349. GetDCs(
  350. LPWSTR Name)
  351. {
  352. NTSTATUS NtStatus;
  353. IO_STATUS_BLOCK IoStatusBlock;
  354. WCHAR *wCp;
  355. NtStatus = NtFsControlFile(
  356. DriverHandle,
  357. NULL, // Event,
  358. NULL, // ApcRoutine,
  359. NULL, // ApcContext,
  360. &IoStatusBlock,
  361. FSCTL_DFS_GET_SPC_TABLE,
  362. Name,
  363. (wcslen(Name) + 1) * sizeof(WCHAR),
  364. OutBuf2,
  365. sizeof(OutBuf2));
  366. if (NtStatus == STATUS_SUCCESS) {
  367. wCp = (WCHAR *)OutBuf2;
  368. while (*wCp) {
  369. MyPrintf(L"\t[%ws]\r\n", wCp);
  370. wCp += wcslen(wCp) + 1;
  371. }
  372. }
  373. }