//-------------------------------------------------------------------------- // // Copyright (C) 1999, Microsoft Corporation // // File: info.cxx // //-------------------------------------------------------------------------- #define UNICODE 1 #include #include #include #include #include #include #include #include #include #include #include #include #include "struct.hxx" #include "misc.hxx" #define OFFSET_TO_POINTER(f,b) \ ((VOID *)((PCHAR)(f) + (ULONG_PTR)(b))) CHAR *OutBuf = NULL; ULONG OutBufSize = 0x1000; HANDLE DriverHandle = NULL; CHAR InBuf[0x1000]; CHAR OutBuf2[0x1000]; VOID GetDCs( LPWSTR Name); DWORD PktInfo( BOOLEAN fSwDfs, LPWSTR pwszHexValue) { DWORD dwErr = ERROR_SUCCESS; NTSTATUS NtStatus; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES objectAttributes; UNICODE_STRING DfsDriverName; ULONG Type; ULONG State; ULONG Entry; ULONG Service; ULONG Level = 0; PDFS_GET_PKT_ARG pGetPkt = NULL; OutBuf = (PCHAR) malloc(OutBufSize); if (OutBuf == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } if (fSwDfs == TRUE) { MyPrintf(L"--dfs.sys--\r\n"); RtlInitUnicodeString(&DfsDriverName, DFS_SERVER_NAME); } else { MyPrintf(L"--mup.sys--\r\n"); RtlInitUnicodeString(&DfsDriverName, DFS_DRIVER_NAME); } if (pwszHexValue != NULL) { Level = AtoHex(pwszHexValue, &dwErr); if (dwErr != ERROR_SUCCESS) { MyPrintf(L"Bad Level %ws\r\n", pwszHexValue); goto Cleanup; } } InitializeObjectAttributes( &objectAttributes, &DfsDriverName, OBJ_CASE_INSENSITIVE, NULL, NULL); NtStatus = NtCreateFile( &DriverHandle, SYNCHRONIZE, &objectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN_IF, FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (!NT_SUCCESS(NtStatus)) { dwErr = RtlNtStatusToDosError(NtStatus); if (fSwDebug) MyPrintf(L"NtCreateFile returned 0x%x\r\n", NtStatus); goto Cleanup; } TryAgain: NtStatus = NtFsControlFile( DriverHandle, NULL, // Event, NULL, // ApcRoutine, NULL, // ApcContext, &IoStatusBlock, FSCTL_DFS_GET_PKT, NULL, 0, OutBuf, OutBufSize); if (NtStatus == STATUS_BUFFER_OVERFLOW) { OutBufSize = *((ULONG *)OutBuf); free(OutBuf); OutBuf = (PCHAR) malloc(OutBufSize); if (OutBuf == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } goto TryAgain; } dwErr = RtlNtStatusToDosError(NtStatus); if (!NT_SUCCESS(NtStatus)) goto Cleanup; pGetPkt = (PDFS_GET_PKT_ARG)OutBuf; MyPrintf(L"%d entries...\r\n", pGetPkt->EntryCount); for (Entry = 0; Entry < pGetPkt->EntryCount; Entry++) { pGetPkt->EntryObject[Entry].Prefix = (LPWSTR) OFFSET_TO_POINTER( pGetPkt->EntryObject[Entry].Prefix, OutBuf); pGetPkt->EntryObject[Entry].ShortPrefix = (LPWSTR) OFFSET_TO_POINTER( pGetPkt->EntryObject[Entry].ShortPrefix, OutBuf); pGetPkt->EntryObject[Entry].Address = (PDFS_PKT_ADDRESS_OBJECT *) OFFSET_TO_POINTER( pGetPkt->EntryObject[Entry].Address, OutBuf); for (Service = 0; Service < pGetPkt->EntryObject[Entry].ServiceCount; Service++) { pGetPkt->EntryObject[Entry].Address[Service] = (PDFS_PKT_ADDRESS_OBJECT) OFFSET_TO_POINTER( pGetPkt->EntryObject[Entry].Address[Service], OutBuf); } } for (Entry = 0; Entry < pGetPkt->EntryCount; Entry++) { MyPrintf(L"Entry: %ws\r\n", pGetPkt->EntryObject[Entry].Prefix); MyPrintf(L"ShortEntry: %ws\r\n", pGetPkt->EntryObject[Entry].ShortPrefix); MyPrintf(L"Expires in %d seconds\r\n", pGetPkt->EntryObject[Entry].ExpireTime); MyPrintf(L"UseCount: %d Type:0x%x (", pGetPkt->EntryObject[Entry].UseCount, pGetPkt->EntryObject[Entry].Type); Type = pGetPkt->EntryObject[Entry].Type; if (Type & PKT_ENTRY_TYPE_OFFLINE) MyPrintf(L" OFFLINE"); if (Type & PKT_ENTRY_TYPE_LOCAL) MyPrintf(L" LOCAL"); if (Type & PKT_ENTRY_TYPE_STALE) MyPrintf(L" STALE"); if (Type & PKT_ENTRY_TYPE_LOCAL_XPOINT) MyPrintf(L" LOCAL_XPOINT"); if (Type & PKT_ENTRY_TYPE_DELETE_PENDING) MyPrintf(L" DELETE_PENDING"); if (Type & PKT_ENTRY_TYPE_PERMANENT) MyPrintf(L" PERMANENT"); if (Type & PKT_ENTRY_TYPE_REFERRAL_SVC) MyPrintf(L" REFERRAL_SVC"); if (Type & PKT_ENTRY_TYPE_SYSVOL) MyPrintf(L" SYSVOL"); if (Type & PKT_ENTRY_TYPE_OUTSIDE_MY_DOM) MyPrintf(L" OUTSIDE_MY_DOM"); if (Type & PKT_ENTRY_TYPE_LEAFONLY) MyPrintf(L" LEAFONLY"); if (Type & PKT_ENTRY_TYPE_NONDFS) MyPrintf(L" NONDFS"); if (Type & PKT_ENTRY_TYPE_MACHINE) MyPrintf(L" MACHINE"); if (Type & PKT_ENTRY_TYPE_DFS) MyPrintf(L" DFS"); if (Type & PKT_ENTRY_TYPE_INSITE_ONLY) MyPrintf(L" INSITE"); MyPrintf(L" )\r\n"); for (Service = 0; Service < pGetPkt->EntryObject[Entry].ServiceCount; Service++) { MyPrintf(L"%4d:[%ws] State:0x%02x ", Service, pGetPkt->EntryObject[Entry].Address[Service]->ServerShare, pGetPkt->EntryObject[Entry].Address[Service]->State); State = pGetPkt->EntryObject[Entry].Address[Service]->State; // // Ugly - used to have State == 0x1 mean 'active'. Now we return an // ULONG with multiple bits set, so 0x1 indicates the old way and // more than 1 bit set means the new way. // if (State == 0x0) { MyPrintf(L"\r\n"); } else if (State == 0x1) { MyPrintf(L"( ACTIVE )\r\n"); } else { MyPrintf(L"("); if (State & DFS_SERVICE_TYPE_ACTIVE) MyPrintf(L" ACTIVE"); if (State & DFS_SERVICE_TYPE_OFFLINE) MyPrintf(L" OFFLINE"); if (Level >= 1) { if (State & DFS_SERVICE_TYPE_MASTER) MyPrintf(L" MASTER"); if (State & DFS_SERVICE_TYPE_READONLY) MyPrintf(L" READONLY"); if (State & DFS_SERVICE_TYPE_LOCAL) MyPrintf(L" LOCAL"); if (State & DFS_SERVICE_TYPE_REFERRAL) MyPrintf(L" REFERRAL"); if (State & DFS_SERVICE_TYPE_DOWN_LEVEL) MyPrintf(L" DOWNLEVEL"); if (State & DFS_SERVICE_TYPE_COSTLIER) MyPrintf(L" COSTLIER"); } MyPrintf(L" )\r\n"); } } MyPrintf(L"\r\n"); } Cleanup: if (OutBuf != NULL) { free(OutBuf); OutBuf = NULL; } if (DriverHandle != NULL) { NTSTATUS st; st = NtClose(DriverHandle); DriverHandle = NULL; } return dwErr; } DWORD SpcInfo( BOOLEAN fSwAll) { DWORD dwErr = ERROR_SUCCESS; NTSTATUS NtStatus; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES objectAttributes; UNICODE_STRING DfsDriverName; WCHAR *wCp; OutBuf = (PCHAR) malloc(OutBufSize); if (OutBuf == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } RtlInitUnicodeString(&DfsDriverName, DFS_DRIVER_NAME); InitializeObjectAttributes( &objectAttributes, &DfsDriverName, OBJ_CASE_INSENSITIVE, NULL, NULL); NtStatus = NtCreateFile( &DriverHandle, SYNCHRONIZE, &objectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN_IF, FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (!NT_SUCCESS(NtStatus)) { dwErr = RtlNtStatusToDosError(NtStatus); if (fSwDebug) MyPrintf(L"NtCreateFile returned 0x%x\r\n", NtStatus); goto Cleanup; } TryAgain: wcscpy((WCHAR *)InBuf, L"*"); NtStatus = NtFsControlFile( DriverHandle, NULL, // Event, NULL, // ApcRoutine, NULL, // ApcContext, &IoStatusBlock, FSCTL_DFS_GET_SPC_TABLE, InBuf, sizeof(InBuf), OutBuf, OutBufSize); if (NtStatus == STATUS_BUFFER_OVERFLOW) { OutBufSize = *((ULONG *)OutBuf); free(OutBuf); OutBuf = (PCHAR)malloc(OutBufSize); if (OutBuf == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } goto TryAgain; } dwErr = RtlNtStatusToDosError(NtStatus); if (NtStatus == STATUS_SUCCESS) { wCp = (WCHAR *)OutBuf; while (*wCp) { MyPrintf(L"[%c][%ws]\r\n", *wCp, (wCp+1)); wCp += wcslen(wCp) + 1; } } wcscpy((WCHAR *)InBuf, L""); NtStatus = NtFsControlFile( DriverHandle, NULL, // Event, NULL, // ApcRoutine, NULL, // ApcContext, &IoStatusBlock, FSCTL_DFS_GET_SPC_TABLE, InBuf, sizeof(InBuf), OutBuf, OutBufSize); if (NtStatus == STATUS_BUFFER_OVERFLOW) { OutBufSize = *((ULONG *)OutBuf); OutBuf = (PCHAR)malloc(OutBufSize); if (OutBuf == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } goto TryAgain; } dwErr = RtlNtStatusToDosError(NtStatus); if (NtStatus == STATUS_SUCCESS) { wCp = (WCHAR *)OutBuf; while (*wCp) { MyPrintf(L"[%c][%ws]\r\n", *wCp, (wCp+1)); if (fSwAll == TRUE || *wCp == '+') { GetDCs((wCp+1)); } wCp += wcslen(wCp) + 1; } } Cleanup: if (DriverHandle != NULL) { NtClose(DriverHandle); DriverHandle = NULL; } if (OutBuf != NULL) { free(OutBuf); OutBuf = NULL; } return dwErr; } VOID GetDCs( LPWSTR Name) { NTSTATUS NtStatus; IO_STATUS_BLOCK IoStatusBlock; WCHAR *wCp; NtStatus = NtFsControlFile( DriverHandle, NULL, // Event, NULL, // ApcRoutine, NULL, // ApcContext, &IoStatusBlock, FSCTL_DFS_GET_SPC_TABLE, Name, (wcslen(Name) + 1) * sizeof(WCHAR), OutBuf2, sizeof(OutBuf2)); if (NtStatus == STATUS_SUCCESS) { wCp = (WCHAR *)OutBuf2; while (*wCp) { MyPrintf(L"\t[%ws]\r\n", wCp); wCp += wcslen(wCp) + 1; } } }