WindowsXP-SP1/base/fs/remotefs/dfs/tools/dfsutil/misc.cxx
2020-09-30 16:53:49 +02:00

778 lines
19 KiB
C++

//--------------------------------------------------------------------------
//
// Copyright (C) 1999, Microsoft Corporation
//
// File: misc.cxx
//
//--------------------------------------------------------------------------
#define UNICODE 1
#include <stdio.h>
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <shellapi.h>
#include <winldap.h>
#include <stdlib.h>
#include <dsgetdc.h>
#include <lm.h>
#include <lmdfs.h>
#include <dfsfsctl.h>
#include "struct.hxx"
#include "flush.hxx"
#include "misc.hxx"
#include "messages.h"
#define MAX_BUF_SIZE 10000
WCHAR MsgBuf[MAX_BUF_SIZE];
CHAR AnsiBuf[MAX_BUF_SIZE*3];
WCHAR wszRootShare[MAX_PATH+1] = { 0 };
#define WINLOGON_FOLDER L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"
#define SFCVALUE L"SFCDisable"
#define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
DWORD
DfspGetLinkName(
LPWSTR pwszDfsRoot,
LPWSTR *ppwszLinkName);
DWORD
AtoHex(
LPWSTR pwszHexValue,
PDWORD pdwErr)
{
DWORD dwHexValue = 0;
// if (fSwDebug == TRUE)
// MyPrintf(L"AtoHex(%ws)\r\n", pwszHexValue);
if (pwszHexValue == NULL) {
*pdwErr = ERROR_INVALID_PARAMETER;
goto AllDone;
}
if (pwszHexValue[0] == L'0' && (pwszHexValue[1] == L'x' || pwszHexValue[1] == L'X'))
pwszHexValue = &pwszHexValue[2];
swscanf(pwszHexValue, L"%x", &dwHexValue);
AllDone:
// if (fSwDebug == TRUE)
// MyPrintf(L"AtoHex returning 0x%x (dwErr=0x%x)\r\n", dwHexValue, *pdwErr);
return dwHexValue;
}
DWORD
AtoDec(
LPWSTR pwszDecValue,
PDWORD pdwErr)
{
DWORD dwDecValue = 0;
// if (fSwDebug == TRUE)
// MyPrintf(L"AtoDec(%ws)\r\n", pwszDecValue);
if (pwszDecValue == NULL) {
*pdwErr = ERROR_INVALID_PARAMETER;
goto AllDone;
}
swscanf(pwszDecValue, L"%d", &dwDecValue);
AllDone:
// if (fSwDebug == TRUE)
// MyPrintf(L"AtoDec returning 0x%x (dwErr=0x%x)\r\n", dwDecValue, *pdwErr);
return dwDecValue;
}
DWORD
CmdCscOnLine(
LPWSTR pwszServerName)
{
DWORD dwErr = STATUS_SUCCESS;
NTSTATUS NtStatus;
HANDLE DriverHandle = NULL;
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES objectAttributes;
UNICODE_STRING DfsDriverName;
ULONG Type = 0;
if (fSwDebug)
MyPrintf(L"CmdCscOnLine(%ws)\r\n", pwszServerName);
if (pwszServerName == NULL)
pwszServerName = L"";
MyPrintf(L"ServerName=[%ws]\r\n", pwszServerName);
RtlInitUnicodeString(&DfsDriverName, DFS_DRIVER_NAME);
InitializeObjectAttributes(
&objectAttributes,
&DfsDriverName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
NtStatus = NtCreateFile(
&DriverHandle,
SYNCHRONIZE | FILE_WRITE_DATA,
&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;
}
NtStatus = NtFsControlFile(
DriverHandle,
NULL, // Event,
NULL, // ApcRoutine,
NULL, // ApcContext,
&IoStatusBlock,
FSCTL_DFS_CSC_SERVER_ONLINE,
pwszServerName,
wcslen(pwszServerName) * sizeof(WCHAR),
NULL,
0);
NtClose(DriverHandle);
if (!NT_SUCCESS(NtStatus)) {
if (fSwDebug)
MyPrintf(L"NtFsControlFile returned 0x%x\r\n", NtStatus);
}
dwErr = RtlNtStatusToDosError(NtStatus);
Cleanup:
if (fSwDebug && dwErr != ERROR_SUCCESS)
MyPrintf(L"CmdCscOnLine exit %d\r\n", dwErr);
return(dwErr);
}
DWORD
CmdCscOffLine(
LPWSTR pwszServerName)
{
DWORD dwErr = STATUS_SUCCESS;
NTSTATUS NtStatus;
HANDLE DriverHandle = NULL;
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES objectAttributes;
UNICODE_STRING DfsDriverName;
ULONG Type = 0;
if (fSwDebug)
MyPrintf(L"CmdCscOffLine(%ws)\r\n", pwszServerName);
if (pwszServerName == NULL)
pwszServerName = L"";
MyPrintf(L"ServerName=[%ws]\r\n", pwszServerName);
RtlInitUnicodeString(&DfsDriverName, DFS_DRIVER_NAME);
InitializeObjectAttributes(
&objectAttributes,
&DfsDriverName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
NtStatus = NtCreateFile(
&DriverHandle,
SYNCHRONIZE | FILE_WRITE_DATA,
&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;
}
NtStatus = NtFsControlFile(
DriverHandle,
NULL, // Event,
NULL, // ApcRoutine,
NULL, // ApcContext,
&IoStatusBlock,
FSCTL_DFS_CSC_SERVER_OFFLINE,
pwszServerName,
wcslen(pwszServerName) * sizeof(WCHAR),
NULL,
0);
NtClose(DriverHandle);
if (!NT_SUCCESS(NtStatus)) {
if (fSwDebug)
MyPrintf(L"NtFsControlFile returned 0x%x\r\n", NtStatus);
}
dwErr = RtlNtStatusToDosError(NtStatus);
Cleanup:
if (fSwDebug && dwErr != ERROR_SUCCESS)
MyPrintf(L"CmdCscOffLine exit %d\r\n", dwErr);
return(dwErr);
}
DWORD
CmdDfsFsctlDfs(
LPWSTR DriverName,
DWORD FsctlCmd)
{
DWORD dwErr = STATUS_SUCCESS;
NTSTATUS NtStatus;
HANDLE DriverHandle = NULL;
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES objectAttributes;
UNICODE_STRING DfsDriverName;
ULONG Type = 0;
if (fSwDebug)
MyPrintf(L"CmdDfsFsctlDfs(0x%x)\r\n", FsctlCmd);
RtlInitUnicodeString(&DfsDriverName, DriverName);
InitializeObjectAttributes(
&objectAttributes,
&DfsDriverName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
NtStatus = NtCreateFile(
&DriverHandle,
SYNCHRONIZE | FILE_WRITE_DATA,
&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;
}
NtStatus = NtFsControlFile(
DriverHandle,
NULL, // Event,
NULL, // ApcRoutine,
NULL, // ApcContext,
&IoStatusBlock,
FsctlCmd,
NULL,
0,
NULL,
0);
NtClose(DriverHandle);
if (!NT_SUCCESS(NtStatus)) {
if (fSwDebug)
MyPrintf(L"NtFsControlFile returned 0x%x\r\n", NtStatus);
}
dwErr = RtlNtStatusToDosError(NtStatus);
Cleanup:
if (fSwDebug && dwErr != ERROR_SUCCESS)
MyPrintf(L"CmdDfsFsctlDfs exit %d\r\n", dwErr);
return(dwErr);
}
#if 0
DWORD
CmdSetOnSite(
LPWSTR pwszDfsRoot,
LPWSTR pwszDcName,
PSEC_WINNT_AUTH_IDENTITY pAuthIdent,
ULONG set)
{
DWORD dwErr = ERROR_SUCCESS;
LPWSTR pwszDfsName = NULL;
LPWSTR pwszShareName = NULL;
LPWSTR pwszLinkName = NULL;
WCHAR wszDomDfsName[MAX_PATH+1];
BOOLEAN IsFtRoot = FALSE;
DWORD cbName;
DWORD dwType;
HKEY hKey = NULL;
HKEY rKey = NULL;
BOOLEAN IsDomainName = FALSE;
dwErr = DfspParseName(pwszDfsRoot, &pwszDfsName, &pwszShareName);
if (dwErr != ERROR_SUCCESS)
goto Cleanup;
dwErr = DfspGetLinkName(pwszDfsRoot, &pwszLinkName);
if (dwErr != ERROR_SUCCESS)
goto Cleanup;
dwErr = DfspIsDomainName(
pwszDfsName,
pwszDcName,
&IsDomainName);
if (dwErr != ERROR_SUCCESS)
goto Cleanup;
if (IsDomainName == TRUE) {
dwErr = DfsSetFtOnSite(pwszDfsName, pwszShareName, pwszLinkName, pwszDcName, pAuthIdent, set);
}
else {
dwErr = RegConnectRegistry( pwszDfsName, HKEY_LOCAL_MACHINE, &rKey);
if (dwErr != ERROR_SUCCESS) {
ErrorMessage(MSG_CAN_NOT_CONNECT, pwszDfsName);
goto Cleanup;
}
dwErr = RegOpenKey(rKey, VOLUMES_DIR, &hKey);
if (dwErr == ERROR_SUCCESS) {
cbName = MAX_PATH;
dwErr = RegQueryValueEx(
hKey,
FTDFS_VALUE_NAME,
NULL,
&dwType,
(PBYTE) wszDomDfsName,
&cbName);
if (dwErr == ERROR_MORE_DATA)
dwErr = ERROR_SUCCESS;
if (dwErr == ERROR_SUCCESS && dwType == REG_SZ)
IsFtRoot = TRUE;
} else {
MyPrintf(L"Not a Dfs root\r\n");
goto Cleanup;
}
if (IsFtRoot == TRUE) {
MyPrintf(L"Not a Std Dfs root\r\n");
goto Cleanup;
}
dwErr = DfsSetOnSite(rKey, pwszLinkName, set);
}
Cleanup:
if (pwszDfsName != NULL)
free(pwszDfsName);
if (pwszShareName != NULL)
free(pwszShareName);
if (pwszLinkName != NULL)
free(pwszLinkName);
if (rKey != NULL)
RegCloseKey(rKey);
if (hKey != NULL)
RegCloseKey(hKey);
return dwErr;
}
#endif
DWORD
CmdAddRoot(
BOOLEAN DomainDfs,
LPWSTR pwszServerName,
LPWSTR pwszShareName,
LPWSTR pwszComment)
{
DWORD dwErr = ERROR_SUCCESS;
if (fSwDebug == TRUE)
MyPrintf(L"CmdAddRoot(%ws,%ws,%ws,%ws)\r\n",
pwszServerName,
pwszShareName,
pwszComment);
if (DomainDfs == FALSE)
{
dwErr = NetDfsAddStdRoot(
pwszServerName,
pwszShareName,
pwszComment,
0);
} else {
dwErr = NetDfsAddFtRoot(
pwszServerName,
pwszShareName,
pwszShareName,
pwszComment,
0);
}
if (fSwDebug == TRUE)
MyPrintf(L"CmdAddRoot returning %d\r\n", dwErr);
return dwErr;
}
DWORD
CmdRemRoot(
BOOLEAN DomDfs,
LPWSTR pwszServerName,
LPWSTR pwszShareName)
{
DWORD dwErr = ERROR_SUCCESS;
if (fSwDebug == TRUE)
MyPrintf(L"CmdRemRoot(%ws,%ws)\r\n",
pwszServerName,
pwszShareName);
if (DomDfs == FALSE)
{
dwErr = NetDfsRemoveStdRoot(
pwszServerName,
pwszShareName,
0);
}
else {
dwErr = NetDfsRemoveFtRoot(
pwszServerName,
pwszShareName,
pwszShareName,
0);
}
if (fSwDebug == TRUE)
MyPrintf(L"CmdRemRoot returning %d\r\n", dwErr);
return dwErr;
}
DWORD
DfspIsDomainName(
LPWSTR pwszDomainName,
LPWSTR pwszDcName,
PBOOLEAN pIsDomainName)
{
PDS_DOMAIN_TRUSTS pDsDomainTrusts = NULL;
PDOMAIN_CONTROLLER_INFO pDcInfo = NULL;
ULONG DsDomainCount = 0;
DWORD dwErr = ERROR_SUCCESS;
ULONG i;
if (fSwDebug == TRUE)
MyPrintf(L"DfspIsDomainName(%ws,%ws)\r\n", pwszDomainName, pwszDcName);
if (pwszDcName == NULL) {
dwErr = DsGetDcName(
NULL, // Computer to remote to
NULL, // Domain
NULL, // Domain Guid
NULL, // Site Guid
DS_FORCE_REDISCOVERY,
&pDcInfo);
if (dwErr != ERROR_SUCCESS) {
if (fSwDebug == TRUE)
MyPrintf(L"DsGetDcName() returned %d\r\n", dwErr);
goto Cleanup;
}
pwszDcName = &pDcInfo->DomainControllerName[2];
}
dwErr = DsEnumerateDomainTrusts(
pwszDcName,
DS_DOMAIN_VALID_FLAGS,
&pDsDomainTrusts,
&DsDomainCount);
if (dwErr != ERROR_SUCCESS) {
if (fSwDebug == TRUE)
MyPrintf(L"DsEnumerateDomainTrusts() returned %d\r\n", dwErr);
goto Cleanup;
}
*pIsDomainName = FALSE;
for (i = 0; i < DsDomainCount; i++) {
if (
(pDsDomainTrusts[i].NetbiosDomainName != NULL &&
_wcsicmp(pwszDomainName, pDsDomainTrusts[i].NetbiosDomainName) == 0)
||
(pDsDomainTrusts[i].DnsDomainName != NULL &&
_wcsicmp(pwszDomainName, pDsDomainTrusts[i].DnsDomainName) == 0)
) {
*pIsDomainName = TRUE;
goto Cleanup;
}
}
Cleanup:
if (pDsDomainTrusts != NULL)
NetApiBufferFree(pDsDomainTrusts);
if (pDcInfo != NULL)
NetApiBufferFree(pDcInfo);
if (fSwDebug == TRUE)
MyPrintf(
L"DfspIsDomainName returning %d (%s)\r\n",
dwErr, *pIsDomainName == TRUE ? "T" : "F");
if (dwErr == ERROR_NO_SUCH_DOMAIN)
{
*pIsDomainName = FALSE;
dwErr = ERROR_SUCCESS;
}
return dwErr;
}
DWORD
DfspParseName(
LPWSTR pwszDfsRoot,
LPWSTR *ppwszDfsName,
LPWSTR *ppwszShareName)
{
DWORD dwErr = ERROR_SUCCESS;
LPWSTR pwszDfsName = NULL;
LPWSTR pwszShareName = NULL;
WCHAR *wCp1 = NULL;
WCHAR *wCp2 = NULL;
ULONG Len = 0;
if (fSwDebug == TRUE)
MyPrintf(L"DfspParseName(%ws)\r\n", pwszDfsRoot);
wCp1 = pwszDfsRoot;
while (*wCp1 == UNICODE_PATH_SEP && *wCp1 != UNICODE_NULL)
wCp1++;
if (*wCp1 == UNICODE_NULL) {
dwErr = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
wCp2 = wCp1;
while (*wCp2 != UNICODE_PATH_SEP && *wCp2 != UNICODE_NULL)
wCp2++;
if (*wCp2 == UNICODE_NULL) {
dwErr = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
Len = (ULONG)((wCp2 - wCp1) * sizeof(WCHAR));
pwszDfsName = (LPWSTR)malloc(Len + sizeof(WCHAR));
if (pwszDfsName == NULL) {
dwErr = ERROR_OUTOFMEMORY;
goto Cleanup;
}
RtlZeroMemory(pwszDfsName,Len+sizeof(WCHAR));
RtlCopyMemory(pwszDfsName, wCp1, Len);
wCp1 = wCp2;
while (*wCp1 == UNICODE_PATH_SEP && *wCp1 != UNICODE_NULL)
wCp1++;
if (*wCp1 == UNICODE_NULL) {
dwErr = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
wCp2 = wCp1;
while (*wCp2 != UNICODE_PATH_SEP && *wCp2 != UNICODE_NULL)
wCp2++;
Len = (ULONG)((wCp2 - wCp1) * sizeof(WCHAR));
pwszShareName = (LPWSTR)malloc(Len + sizeof(WCHAR));
if (pwszShareName == NULL) {
dwErr = ERROR_OUTOFMEMORY;
goto Cleanup;
}
RtlZeroMemory(pwszShareName,Len+sizeof(WCHAR));
RtlCopyMemory(pwszShareName, wCp1, Len);
*ppwszDfsName = pwszDfsName;
*ppwszShareName = pwszShareName;
Cleanup:
if (dwErr != ERROR_SUCCESS) {
if (pwszDfsName != NULL)
free(pwszDfsName);
if (pwszShareName != NULL)
free(pwszShareName);
}
if (fSwDebug == TRUE)
MyPrintf(L"DfspParseName returning %d\r\n", dwErr);
return dwErr;
}
DWORD
DfspGetLinkName(
LPWSTR pwszDfsRoot,
LPWSTR *ppwszLinkName)
{
WCHAR *wCp1 = NULL;
WCHAR *wCp2 = NULL;
ULONG Len = 0;
DWORD dwErr = ERROR_SUCCESS;
wCp1 = pwszDfsRoot;
while (*wCp1 == UNICODE_PATH_SEP && *wCp1 != UNICODE_NULL)
wCp1++;
if (*wCp1 == UNICODE_NULL) {
dwErr = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
while (*wCp1 != UNICODE_PATH_SEP && *wCp1 != UNICODE_NULL)
wCp1++;
if (*wCp1 == UNICODE_NULL) {
dwErr = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
*ppwszLinkName = ++wCp1;
Cleanup:
return dwErr;
}
VOID
MyFormatMessageText(
HRESULT dwMsgId,
PWSTR pszBuffer,
DWORD dwBufferSize,
va_list *parglist)
{
DWORD dwReturn = FormatMessage(
(dwMsgId >= MSG_FIRST_MESSAGE)
? FORMAT_MESSAGE_FROM_HMODULE
: FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwMsgId,
LANG_USER_DEFAULT,
pszBuffer,
dwBufferSize,
parglist);
if (dwReturn == 0)
MyPrintf(L"Formatmessage failed 0x%x\r\n", GetLastError());
}
VOID
ErrorMessage(
IN HRESULT hr,
...)
{
ULONG cch;
va_list arglist;
va_start(arglist, hr);
MyFormatMessageText(hr, MsgBuf, ARRAYLEN(MsgBuf), &arglist);
cch = WideCharToMultiByte(CP_OEMCP, 0,
MsgBuf, wcslen(MsgBuf),
AnsiBuf, MAX_BUF_SIZE*3,
NULL, NULL);
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), AnsiBuf, cch, &cch, NULL);
va_end(arglist);
}
VOID
MyPrintf(
PWCHAR format,
...)
{
ULONG cch;
va_list va;
va_start(va, format);
wvsprintf(MsgBuf, format, va);
cch = WideCharToMultiByte(CP_OEMCP, 0,
MsgBuf, wcslen(MsgBuf),
AnsiBuf, MAX_BUF_SIZE*3,
NULL, NULL);
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), AnsiBuf, cch, &cch, NULL);
va_end(va);
return;
}
VOID
MyFPrintf(
HANDLE hHandle,
PWCHAR format,
...)
{
ULONG cch;
va_list va;
va_start(va, format);
wvsprintf(MsgBuf, format, va);
cch = WideCharToMultiByte(CP_OEMCP, 0,
MsgBuf, wcslen(MsgBuf),
AnsiBuf, MAX_BUF_SIZE*3,
NULL, NULL);
WriteFile(hHandle, AnsiBuf, cch, &cch, NULL);
va_end(va);
return;
}