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.
1355 lines
40 KiB
1355 lines
40 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997.
|
|
//
|
|
// File: N W C L I I N F . C P P
|
|
//
|
|
// Contents: NetWare client configuration notify object.
|
|
// Functionality from old INF
|
|
//
|
|
// Notes:
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
#include "lmerr.h"
|
|
#include "lmcons.h"
|
|
#include "lmserver.h"
|
|
#include "ncreg.h"
|
|
#include "nwclidef.h"
|
|
#include "nwcliobj.h"
|
|
|
|
extern const WCHAR c_szRegKeyCtlLsa[];
|
|
|
|
//---[ Constants ]------------------------------------------------------------
|
|
|
|
const WCHAR c_szConfigDLLName[] = NW_CONFIG_DLL_NAME;
|
|
const WCHAR c_szAuthPackageName[] = NW_AUTH_PACKAGE_NAME;
|
|
const WCHAR c_szParamOptionKeyPath[] = NW_NWC_PARAM_OPTION_KEY;
|
|
const WCHAR c_szParamLogonKeyPath[] = NW_NWC_PARAM_LOGON_KEY;
|
|
|
|
const WCHAR c_szNwDocGWHelpName[] = L"nwdocgw.hlp";
|
|
const WCHAR c_szNwDocGWCNTName[] = L"nwdocgw.cnt";
|
|
const WCHAR c_szNwDocHelpName[] = L"nwdoc.hlp";
|
|
const WCHAR c_szNwDocCNTName[] = L"nwdoc.cnt";
|
|
|
|
const DWORD c_dwOptionKeyPermissions = KEY_SET_VALUE | KEY_CREATE_SUB_KEY;
|
|
|
|
//---[ Prototypes ]-----------------------------------------------------------
|
|
|
|
// See the function headers for descriptions
|
|
//
|
|
HRESULT HrAppendNetwareToAuthPackages();
|
|
HRESULT HrCreateParametersSubkeys();
|
|
HRESULT HrMungeAutoexecNT();
|
|
BOOL FMoveSzToEndOfFile( PSTR pszAutoexecName, PSTR pszMatch);
|
|
HRESULT HrAddNetWareToWOWKnownList();
|
|
HRESULT HrUpdateLanmanSharedDrivesValue();
|
|
HRESULT HrRemoveNetwareFromAuthPackages();
|
|
HRESULT HrRemoveNetWareFromWOWKnownList();
|
|
HRESULT HrDeleteParametersSubkeys();
|
|
HRESULT HrRenameNWDocFiles();
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CNWClient::HrLoadConfigDLL
|
|
//
|
|
// Purpose: Load nwcfg.dll, so we can call some of the functions within.
|
|
// Also, do the GetProcAddress calls for all of the functions
|
|
// that we might need.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK or valid Win32 error code.
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT CNWClient::HrLoadConfigDLL()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
AssertSz(!m_hlibConfig, "This should not be getting initialized twice");
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> CNWClient::HrLoadConfigDLL");
|
|
|
|
m_hlibConfig = LoadLibrary(c_szConfigDLLName);
|
|
if (!m_hlibConfig)
|
|
{
|
|
DWORD dwLastError = GetLastError();
|
|
|
|
TraceLastWin32Error("HrLoadConfigDLL() failed");
|
|
|
|
// More specific info
|
|
//
|
|
TraceTag(ttidNWClientCfg,
|
|
"HrLoadConfigDLL() - LoadLibrary failed on %S, Err: %d",
|
|
c_szConfigDLLName, dwLastError);
|
|
|
|
hr = E_FAIL;
|
|
goto Exit;
|
|
}
|
|
|
|
// $$REVIEW: We probably won't need all of these, so make sure that we've
|
|
// cut out the ones that we're no longer using (or have never used).
|
|
//
|
|
m_pfnAppendSzToFile = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "AppendSzToFile");
|
|
m_pfnRemoveSzFromFile = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "RemoveSzFromFile");
|
|
m_pfnGetKernelVersion = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "GetKernelVersion");
|
|
m_pfnSetEverybodyPermission = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "SetEverybodyPermission");
|
|
m_pfnlodctr = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "lodctr");
|
|
m_pfnunlodctr = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "unlodctr");
|
|
m_pfnDeleteGatewayPassword = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "DeleteGatewayPassword");
|
|
m_pfnSetFileSysChangeValue = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "SetFileSysChangeValue");
|
|
m_pfnCleanupRegistryForNWCS = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "CleanupRegistryForNWCS");
|
|
m_pfnSetupRegistryForNWCS = (NWCFG_PROC) GetProcAddress(m_hlibConfig, "SetupRegistryForNWCS");
|
|
|
|
if (!m_pfnAppendSzToFile || !m_pfnRemoveSzFromFile ||
|
|
!m_pfnGetKernelVersion || !m_pfnSetEverybodyPermission ||
|
|
!m_pfnlodctr || !m_pfnunlodctr ||
|
|
!m_pfnDeleteGatewayPassword || !m_pfnSetFileSysChangeValue ||
|
|
!m_pfnCleanupRegistryForNWCS || !m_pfnSetupRegistryForNWCS)
|
|
{
|
|
TraceLastWin32Error("HrLoadConfigDLL() - GetProcAddress failed");
|
|
hr = E_FAIL;
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
TraceTag(ttidNWClientCfgFn, "<< CNWClient::HrLoadConfigDLL");
|
|
TraceError("HrLoadConfigDLL", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CNWClient::FreeConfigDLL
|
|
//
|
|
// Purpose: Free nwcfg.dll, and NULL out the function pointers.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: No return (VOID)
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID CNWClient::FreeConfigDLL()
|
|
{
|
|
TraceTag(ttidNWClientCfgFn, ">> CNWClient::FreeConfigDLL()");
|
|
|
|
// If we successfully loaded the library, free it.
|
|
if (m_hlibConfig)
|
|
{
|
|
// Free up the library resources.
|
|
FreeLibrary(m_hlibConfig);
|
|
m_hlibConfig = NULL;
|
|
|
|
m_pfnAppendSzToFile = NULL;
|
|
m_pfnRemoveSzFromFile = NULL;
|
|
m_pfnGetKernelVersion = NULL;
|
|
m_pfnSetEverybodyPermission = NULL;
|
|
m_pfnlodctr = NULL;
|
|
m_pfnunlodctr = NULL;
|
|
m_pfnDeleteGatewayPassword = NULL;
|
|
m_pfnSetFileSysChangeValue = NULL;
|
|
m_pfnCleanupRegistryForNWCS = NULL;
|
|
m_pfnSetupRegistryForNWCS = NULL;
|
|
}
|
|
|
|
TraceTag(ttidNWClientCfgFn, "<< CNWClient::FreeConfigDLL()");
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CNWClient::HrInstallCodeFromOldINF
|
|
//
|
|
// Purpose: This contains all of the logic from the old oemnsvnw.inf, or
|
|
// at least calls to helper functions that perform all of the
|
|
// logic. This runs pretty much straight through the old
|
|
// installadapter code.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK or valid Win32 error code.
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT CNWClient::HrInstallCodeFromOldINF()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL fResult = FALSE;
|
|
|
|
// Get result from NWCFG functions. We won't use it though.
|
|
PWSTR pszDummy = NULL;
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> CNWClient::HrInstallCodeFromOldINF()");
|
|
|
|
hr = HrLoadConfigDLL();
|
|
if (FAILED(hr))
|
|
{
|
|
// Error traced in the call itself.
|
|
goto Exit;
|
|
}
|
|
|
|
// Call the NWCFG function that does (their comment):
|
|
// "set the FileSysChangeValue to please NETWARE.DRV.
|
|
// also set win.ini parameter so wfwnet.drv knows we are there."
|
|
|
|
fResult = m_pfnSetupRegistryForNWCS(0, NULL, &pszDummy);
|
|
if (!fResult)
|
|
{
|
|
TraceTag(ttidNWClientCfg, "HrInstallCodeFromOldINF() - m_pfnSetupRegistryForNWCS failed");
|
|
goto Exit;
|
|
}
|
|
|
|
// Append our name to the Lsa Authentication packages reg value.
|
|
hr = HrAppendNetwareToAuthPackages();
|
|
if (FAILED(hr))
|
|
{
|
|
// Error traced within the function itself.
|
|
//
|
|
goto Exit;
|
|
}
|
|
|
|
// Create the required subkeys under the services\NWCWorkstation\parameters
|
|
// key
|
|
//
|
|
hr = HrCreateParametersSubkeys();
|
|
if (FAILED(hr))
|
|
{
|
|
// Error traced within the function itself.
|
|
//
|
|
goto Exit;
|
|
}
|
|
|
|
// Munge the autoexec.nt (or autoexec.tmp) file. Pass the function pointers
|
|
// to the munge that will allow it to manipulate the autoexec.nt
|
|
hr = HrMungeAutoexecNT();
|
|
if (FAILED(hr))
|
|
{
|
|
// Error traced within the function itself.
|
|
//
|
|
goto Exit;
|
|
}
|
|
|
|
hr = HrAddNetWareToWOWKnownList();
|
|
if (FAILED(hr))
|
|
{
|
|
// Error traced within the function itself.
|
|
//
|
|
goto Exit;
|
|
}
|
|
|
|
// If this is the gateway that we're installing, do the work that will
|
|
// allow us to share a redirected resource.
|
|
//
|
|
if (PF_SERVER == m_pf)
|
|
{
|
|
hr = HrUpdateLanmanSharedDrivesValue();
|
|
if (FAILED(hr))
|
|
{
|
|
// Error traced within the function itself.
|
|
//
|
|
goto Exit;
|
|
}
|
|
|
|
// On the server build, rename nwdocgw.* to nwdoc.*
|
|
hr = HrRenameNWDocFiles();
|
|
if (FAILED(hr))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
}
|
|
|
|
Exit:
|
|
// This will work even if the handle is NULL.
|
|
FreeConfigDLL();
|
|
|
|
TraceTag(ttidNWClientCfgFn, "<< CNWClient::HrInstallCodeFromOldINF()");
|
|
TraceError("CNWClient::HrInstallCodeFromOldINF()", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CNWClient::HrRemoveCodeFromOldINF
|
|
//
|
|
// Purpose: This contains all of the remove logic from the old
|
|
// oemnsvnw.inf, or at least calls to helper functions that
|
|
// perform all of the logic. This runs pretty much straight
|
|
// through the old removeadapter code.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK or valid Win32 error code.
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT CNWClient::HrRemoveCodeFromOldINF()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL fResult = FALSE;
|
|
|
|
// Get result from NWCFG functions. We won't use it though.
|
|
PWSTR pszDummy = NULL;
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> CNWClient::HrRemoveCodeFromOldINF()");
|
|
|
|
hr = HrLoadConfigDLL();
|
|
if (FAILED(hr))
|
|
{
|
|
// Error traced in the call itself.
|
|
goto Exit;
|
|
}
|
|
|
|
// Call the NWCFG function that does (their comment):
|
|
// "set the FileSysChangeValue to please NETWARE.DRV.
|
|
// also set win.ini parameter so wfwnet.drv knows we are there."
|
|
|
|
fResult = m_pfnCleanupRegistryForNWCS(0, NULL, &pszDummy);
|
|
if (!fResult)
|
|
{
|
|
TraceTag(ttidNWClientCfg, "HrRemoveCodeFromOldINF() - m_pfnCleanupRegistryForNWCS failed");
|
|
goto Exit;
|
|
}
|
|
|
|
// Remove our name from the Lsa Authentication packages reg value.
|
|
hr = HrRemoveNetwareFromAuthPackages();
|
|
if (FAILED(hr))
|
|
{
|
|
// Error traced within the function itself.
|
|
//
|
|
goto Exit;
|
|
}
|
|
|
|
// Delete the NWC subkeys under the services\NWCWorkstation\parameters
|
|
// key
|
|
//
|
|
hr = HrDeleteParametersSubkeys();
|
|
if (FAILED(hr))
|
|
{
|
|
// Error traced within the function itself.
|
|
//
|
|
goto Exit;
|
|
}
|
|
|
|
hr = HrRemoveNetWareFromWOWKnownList();
|
|
if (FAILED(hr))
|
|
{
|
|
// Error traced within the function itself.
|
|
//
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
// This will work even if the handle is NULL.
|
|
FreeConfigDLL();
|
|
|
|
TraceTag(ttidNWClientCfgFn, "<< CNWClient::HrRemoveCodeFromOldINF()");
|
|
TraceError("CNWClient::HrRemoveCodeFromOldINF()", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrAppendNetwareToAuthPackages
|
|
//
|
|
// Purpose: Helper function for HrCodeFromOldINF() - Appends the netware
|
|
// authentication provider name to the end of the LSA
|
|
// authentication packages value.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK or valid Win32 Error code.
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrAppendNetwareToAuthPackages()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> HrAppendNetwareToAuthPackages");
|
|
|
|
// Call the cool new AddString... function
|
|
//
|
|
hr = HrRegAddStringToMultiSz(
|
|
(PWSTR) c_szAuthPackageName,
|
|
HKEY_LOCAL_MACHINE,
|
|
c_szRegKeyCtlLsa,
|
|
L"Authentication Packages",
|
|
STRING_FLAG_ENSURE_AT_END,
|
|
0);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceTag(ttidNWClientCfg, "HrAppendNetwareToAuthPackages() - Failed to "
|
|
"Add string to multi-sz 'Authentication Packages' in key: %S",
|
|
c_szRegKeyCtlLsa);
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
Exit:
|
|
TraceTag(ttidNWClientCfgFn, "<< HrAppendNetwareToAuthPackages");
|
|
TraceError("HrAppendNetwareToAuthPackages", hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrRemoveNetwareFromAuthPackages
|
|
//
|
|
// Purpose: Helper function for HrCodeFromOldINF() - Appends the netware
|
|
// authentication provider name to the end of the LSA
|
|
// authentication packages value.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK or valid Win32 Error code.
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrRemoveNetwareFromAuthPackages()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> HrRemoveNetwareFromAuthPackages");
|
|
|
|
// Call the cool new AddString... function
|
|
//
|
|
hr = HrRegRemoveStringFromMultiSz(
|
|
(PWSTR) c_szAuthPackageName,
|
|
HKEY_LOCAL_MACHINE,
|
|
c_szRegKeyCtlLsa,
|
|
L"Authentication Packages",
|
|
STRING_FLAG_REMOVE_ALL);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceTag(ttidNWClientCfg, "HrRemoveNetwareFromAuthPackages() - Failed to "
|
|
"Remove string to multi-sz 'Authentication Packages' in key: %S",
|
|
c_szRegKeyCtlLsa);
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
Exit:
|
|
TraceTag(ttidNWClientCfgFn, "<< HrRemoveNetwareFromAuthPackages");
|
|
TraceError("HrRemoveNetwareFromAuthPackages", hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrNwLibSetEverybodyPermission
|
|
//
|
|
// Purpose: Set the registry key to everybody "Set Value" (or whatever
|
|
// the caller want.)
|
|
//
|
|
// Arguments:
|
|
// hKey [] The handle of the registry key to set security on
|
|
// dwPermission [] The permission to add to "everybody"
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: jeffspr 18 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrNwLibSetEverybodyPermission( IN HKEY hKey,
|
|
IN DWORD dwPermission)
|
|
{
|
|
LONG err; // error code
|
|
PSECURITY_DESCRIPTOR psd = NULL; // related SD
|
|
PSID pSid = NULL; // original SID
|
|
PACL pDacl = NULL; // Absolute DACL
|
|
PACL pSacl = NULL; // Absolute SACL
|
|
PSID pOSid = NULL; // Absolute Owner SID
|
|
PSID pPSid = NULL; // Absolute Primary SID
|
|
|
|
do { // Not a loop, just for breaking out of error
|
|
//
|
|
// Initialize all the variables...
|
|
//
|
|
// world sid authority
|
|
SID_IDENTIFIER_AUTHORITY SidAuth= SECURITY_WORLD_SID_AUTHORITY;
|
|
DWORD cbSize=0; // Security key size
|
|
PACL pAcl; // original ACL
|
|
BOOL fDaclPresent;
|
|
BOOL fDaclDefault;
|
|
SECURITY_DESCRIPTOR absSD; // Absolute SD
|
|
DWORD AbsSize = sizeof(SECURITY_DESCRIPTOR); // Absolute SD size
|
|
DWORD DaclSize; // Absolute DACL size
|
|
DWORD SaclSize; // Absolute SACL size
|
|
DWORD OSidSize; // Absolute OSID size
|
|
DWORD PSidSize; // Absolute PSID size
|
|
|
|
// Get the original DACL list
|
|
|
|
RegGetKeySecurity( hKey, DACL_SECURITY_INFORMATION, NULL, &cbSize);
|
|
|
|
psd = (PSECURITY_DESCRIPTOR *)LocalAlloc(LMEM_ZEROINIT, cbSize+sizeof(ACCESS_ALLOWED_ACE)+sizeof(ACCESS_MASK)+sizeof(SID));
|
|
pDacl = (PACL)LocalAlloc(LMEM_ZEROINIT, cbSize+sizeof(ACCESS_ALLOWED_ACE)+sizeof(ACCESS_MASK)+sizeof(SID));
|
|
pSacl = (PACL)LocalAlloc(LMEM_ZEROINIT, cbSize);
|
|
pOSid = (PSID)LocalAlloc(LMEM_ZEROINIT, cbSize);
|
|
pPSid = (PSID)LocalAlloc(LMEM_ZEROINIT, cbSize);
|
|
DaclSize = cbSize+sizeof(ACCESS_ALLOWED_ACE)+sizeof(ACCESS_MASK)+sizeof(SID);
|
|
SaclSize = cbSize;
|
|
OSidSize = cbSize;
|
|
PSidSize = cbSize;
|
|
|
|
if (( NULL == psd) ||
|
|
( NULL == pDacl) ||
|
|
( NULL == pSacl) ||
|
|
( NULL == pOSid) ||
|
|
( NULL == pPSid))
|
|
{
|
|
err = ERROR_INSUFFICIENT_BUFFER;
|
|
break;
|
|
}
|
|
|
|
if ( (err = RegGetKeySecurity( hKey, DACL_SECURITY_INFORMATION, psd, &cbSize )) != ERROR_SUCCESS )
|
|
{
|
|
break;
|
|
}
|
|
if ( !GetSecurityDescriptorDacl( psd, &fDaclPresent, &pAcl, &fDaclDefault ))
|
|
{
|
|
err = GetLastError();
|
|
break;
|
|
}
|
|
|
|
// Increase the size for an extra ACE
|
|
|
|
pAcl->AclSize += sizeof(ACCESS_ALLOWED_ACE)+sizeof(ACCESS_MASK)+sizeof(SID);
|
|
|
|
// Get World SID
|
|
|
|
if ( (err = RtlAllocateAndInitializeSid( &SidAuth, 1,
|
|
SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSid)) != ERROR_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Add Permission ACE
|
|
|
|
if ( !AddAccessAllowedAce(pAcl, ACL_REVISION, dwPermission ,pSid))
|
|
{
|
|
err = GetLastError();
|
|
break;
|
|
}
|
|
|
|
// Convert from relate format to absolute format
|
|
|
|
if ( !MakeAbsoluteSD( psd, &absSD, &AbsSize, pDacl, &DaclSize, pSacl, &SaclSize,
|
|
pOSid, &OSidSize, pPSid, &PSidSize ))
|
|
{
|
|
err = GetLastError();
|
|
break;
|
|
}
|
|
|
|
// Set SD
|
|
|
|
if ( !SetSecurityDescriptorDacl( &absSD, TRUE, pAcl, FALSE ))
|
|
{
|
|
err = GetLastError();
|
|
break;
|
|
}
|
|
if ( (err = RegSetKeySecurity( hKey, DACL_SECURITY_INFORMATION, psd ))
|
|
!= ERROR_SUCCESS )
|
|
{
|
|
break;
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
// Clean up the memory
|
|
|
|
RtlFreeSid( pSid );
|
|
LocalFree( psd );
|
|
LocalFree( pDacl );
|
|
LocalFree( pSacl );
|
|
LocalFree( pOSid );
|
|
LocalFree( pPSid );
|
|
|
|
return (HRESULT_FROM_WIN32(err));
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrSetEverybodyPermissionsOnOptionsKeys
|
|
//
|
|
// Purpose: Recurse through the options keys (if any), and set the
|
|
// "Everybody" permissions on them.
|
|
//
|
|
// Arguments:
|
|
// hkeyOptions []
|
|
// dwPermissions []
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: jeffspr 10 Sep 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrSetEverybodyPermissionsOnOptionsKeys(HKEY hkeyOptions, DWORD dwPermissions)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwIndex = 0;
|
|
WCHAR szSubkeyName[MAX_PATH+1];
|
|
FILETIME ft;
|
|
|
|
Assert(hkeyOptions);
|
|
|
|
// First, do it on the root key.
|
|
//
|
|
hr = HrNwLibSetEverybodyPermission(hkeyOptions, dwPermissions);
|
|
|
|
// Enumerate the keys, and set it on them as well
|
|
//
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
DWORD dwSubkeyNameSize = MAX_PATH+1;
|
|
|
|
// Get the next key (starting with 0)
|
|
//
|
|
hr = HrRegEnumKeyEx( hkeyOptions,
|
|
dwIndex++,
|
|
szSubkeyName,
|
|
&dwSubkeyNameSize,
|
|
NULL,
|
|
NULL,
|
|
&ft);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
HKEY hkeyUser = NULL;
|
|
|
|
// Open that key for write
|
|
hr = HrRegOpenKeyEx(hkeyOptions,
|
|
szSubkeyName,
|
|
KEY_ALL_ACCESS,
|
|
&hkeyUser);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = HrNwLibSetEverybodyPermission(hkeyUser, dwPermissions);
|
|
}
|
|
|
|
RegSafeCloseKey(hkeyUser);
|
|
}
|
|
}
|
|
|
|
if (hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
TraceError("HrSetEverybodyPermissionsOnOptionsKeys", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrCreateParametersSubkeys
|
|
//
|
|
// Purpose: Creates the subkeys under the NWCWorkstation parameters key.
|
|
// This could have been done in the INF, but there were some
|
|
// permissions that needed to be set on the keys as well, so
|
|
// all of the work now takes place in this function.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK or valid Win32 error code.
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrCreateParametersSubkeys()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HKEY hkeyOption = NULL;
|
|
HKEY hkeyLogon = NULL;
|
|
DWORD dwDisposition = 0;
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> HrCreateParametersSubkeys");
|
|
|
|
hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
|
c_szParamOptionKeyPath,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hkeyOption,
|
|
&dwDisposition);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceTag(ttidNWClientCfg, "HrCreateParametersSubkeys() - failed to "
|
|
"create/open key %S", c_szParamOptionKeyPath);
|
|
goto Exit;
|
|
}
|
|
|
|
hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
|
c_szParamLogonKeyPath,
|
|
0,
|
|
KEY_SET_VALUE,
|
|
NULL,
|
|
&hkeyLogon,
|
|
&dwDisposition);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceTag(ttidNWClientCfg, "HrCreateParametersSubkeys() - failed to "
|
|
"create/open key %S", c_szParamLogonKeyPath);
|
|
goto Exit;
|
|
}
|
|
|
|
hr = HrSetEverybodyPermissionsOnOptionsKeys(hkeyOption, c_dwOptionKeyPermissions);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceTag(ttidNWClientCfg, "HrSetEverybodyPermissionsOnOptionsKeys failed, hr: 0x%08x", hr);
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
// Close the hkeys, if they're open
|
|
RegSafeCloseKey(hkeyLogon);
|
|
RegSafeCloseKey(hkeyOption);
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> HrCreateParametersSubkeys");
|
|
TraceError("HrCreateParametersSubkeys", hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrDeleteParametersSubkeys
|
|
//
|
|
// Purpose: Deletes the subkeys under the NWCWorkstation parameters key.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK or valid Win32 error code.
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrDeleteParametersSubkeys()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> HrDeleteParametersSubkeys");
|
|
|
|
// Note: We need to be taking ownership of these keys so we can delete
|
|
// them. Regardless, ignore if the key deletions fail.
|
|
|
|
hr = HrRegDeleteKeyTree(HKEY_LOCAL_MACHINE,
|
|
c_szParamOptionKeyPath);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceTag(ttidNWClientCfg, "HrDeleteParametersSubkeys() - failed to "
|
|
"delete key %S, hr = 0x%08x", c_szParamOptionKeyPath, hr);
|
|
hr = S_OK;
|
|
}
|
|
|
|
hr = HrRegDeleteKey(HKEY_LOCAL_MACHINE,
|
|
c_szParamLogonKeyPath);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceTag(ttidNWClientCfg, "HrDeleteParametersSubkeys() - failed to "
|
|
"delete key %S, hr = 0x%08x", c_szParamLogonKeyPath, hr);
|
|
hr = S_OK;
|
|
}
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> HrDeleteParametersSubkeys");
|
|
TraceError("HrDeleteParametersSubkeys", hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FCheckForExistingFile
|
|
//
|
|
// Purpose: Checks for the existance of the passed in file. Should be
|
|
// common-ized.
|
|
//
|
|
// Arguments:
|
|
// pszFileToCheck [] The file name to verify
|
|
//
|
|
// Returns: TRUE if the file was found, FALSE otherwise.
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes: $$TODO: Should be improved if we move this to common code.
|
|
// The thing that it doesn't do is distinguish between a file
|
|
// being "not found" and a file error (such as access rights
|
|
// or sharing violations) on the CreateFile call.
|
|
//
|
|
BOOL FCheckForExistingFile( PSTR pszFileToCheck )
|
|
{
|
|
BOOL fReturn = TRUE;
|
|
HANDLE hFile = NULL;
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> FCheckForExistingFile");
|
|
|
|
hFile = CreateFileA(pszFileToCheck,
|
|
GENERIC_READ,
|
|
0, // No sharing allowed
|
|
NULL, // No security attributes
|
|
OPEN_EXISTING, // Fail if file doesn't exist
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
CloseHandle(hFile);
|
|
hFile = NULL;
|
|
}
|
|
else
|
|
{
|
|
// This was previously a bug. We weren't setting FALSE here, which made
|
|
// the function somewhat useless.
|
|
fReturn = FALSE;
|
|
}
|
|
|
|
TraceTag(ttidNWClientCfgFn, "<< FCheckForExistingFile");
|
|
|
|
return fReturn;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: KillTrailingWhitespace
|
|
//
|
|
// Purpose: Remove whitespace from a non-UNICODE string. This is a utility
|
|
// function for the autoexec.nt parser
|
|
//
|
|
// Arguments:
|
|
// pszKillMyWhitespace [] String from which to remove whitespace
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
VOID KillTrailingWhitespace( PSTR pszKillMyWhitespace )
|
|
{
|
|
long lLength = 0;
|
|
|
|
if (!pszKillMyWhitespace)
|
|
{
|
|
Assert(pszKillMyWhitespace);
|
|
goto Exit;
|
|
}
|
|
|
|
lLength = lstrlenA(pszKillMyWhitespace);
|
|
if (lLength == 0)
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
while (isspace(pszKillMyWhitespace[lLength-1]))
|
|
{
|
|
pszKillMyWhitespace[--lLength] = '\0';
|
|
}
|
|
|
|
Exit:
|
|
return;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FMoveSzToEndOfFile
|
|
//
|
|
// Purpose: Find a string in the file of this name, and if it's present,
|
|
// move the string to the end of the file. This is used by the
|
|
// autoexec.nt parser to move the IPX stuff to the end of the
|
|
// file. This is a rewrite of similar code in the nwcfg.dll
|
|
// stuff. That code apparently wasn't UNICODE, and didn't work
|
|
// for what we were doing.
|
|
//
|
|
// Arguments:
|
|
// pszAutoexecName [] Name of the file to modify
|
|
// pszMatch [] String to move
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
BOOL FMoveSzToEndOfFile( PSTR pszAutoexecName, PSTR pszMatch )
|
|
{
|
|
FILE * hsrcfile = NULL;
|
|
FILE * hdesfile = NULL;
|
|
char * pszTempname = NULL;
|
|
char szInput[1000];
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> FMoveSzToEndOfFile");
|
|
|
|
// Get a temp name
|
|
//
|
|
pszTempname = tmpnam(NULL);
|
|
|
|
// Open the original and the destination files
|
|
//
|
|
hsrcfile = fopen(pszAutoexecName, "r");
|
|
hdesfile = fopen(pszTempname, "w");
|
|
|
|
if (( hsrcfile != NULL ) && ( hdesfile != NULL ))
|
|
{
|
|
while (fgets(szInput,1000,hsrcfile))
|
|
{
|
|
CHAR szInputCopy[1000];
|
|
|
|
// Copy to another temp buffer so that when we remove the
|
|
// trailing whitespace for the comparison, we won't lose the
|
|
// original text.
|
|
//
|
|
strcpy(szInputCopy, szInput);
|
|
|
|
// Remove the trailing whitespace, so we only have to compare the
|
|
// real text
|
|
//
|
|
KillTrailingWhitespace(szInputCopy);
|
|
|
|
// Compare the strings
|
|
//
|
|
if (lstrcmpiA(szInputCopy, pszMatch) != 0)
|
|
{
|
|
// If the strings weren't identical, then we still want
|
|
// to copy the line
|
|
//
|
|
fputs(szInput,hdesfile);
|
|
}
|
|
}
|
|
|
|
// Append the string to the end of the file.
|
|
fputs(pszMatch, hdesfile);
|
|
fputs("\r\n",hdesfile);
|
|
}
|
|
|
|
if (hsrcfile != NULL)
|
|
{
|
|
fclose(hsrcfile);
|
|
}
|
|
|
|
if (hdesfile != NULL)
|
|
{
|
|
fclose(hdesfile);
|
|
}
|
|
|
|
if (( hsrcfile != NULL ) && ( hdesfile != NULL ))
|
|
{
|
|
CopyFileA(pszTempname,pszAutoexecName, FALSE);
|
|
DeleteFileA(pszTempname);
|
|
}
|
|
|
|
TraceTag(ttidNWClientCfgFn, "<< FMoveSzToEndOfFile");
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrMungeAutoexecNT
|
|
//
|
|
// Purpose: Move the IPX stuff to the end of the autoexec.nt. Do this by
|
|
// calling FMoveSzToEndOfFile on each of our lines.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK or valid Win32 error code.
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrMungeAutoexecNT()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CHAR szAutoNTPath[MAX_PATH+1] = {0};
|
|
CHAR szAutoTmpPath[MAX_PATH+1] = {0};
|
|
CHAR szWindowsDirANSI[MAX_PATH+1] = {0};
|
|
PSTR pszAutoPath = NULL;
|
|
BOOL fResult = FALSE;
|
|
PCWSTR pszRem1 = NULL;
|
|
PSTR pszaRem1MultiByte = NULL;
|
|
int iLength = 0;
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> HrMungeAutoexecNT");
|
|
|
|
// Get the windows directory
|
|
if (GetSystemWindowsDirectoryA(szWindowsDirANSI, sizeof(szWindowsDirANSI)) == 0)
|
|
{
|
|
TraceLastWin32Error("HrMungeAutoexecNT - Call to GetWindowsDirectoryA");
|
|
hr = HrFromLastWin32Error();
|
|
goto Exit;
|
|
}
|
|
|
|
// Build the path to the autoexec.nt
|
|
//
|
|
wsprintfA(szAutoNTPath, "%s\\system32\\%s", szWindowsDirANSI, "autoexec.nt");
|
|
if (FCheckForExistingFile(szAutoNTPath) == FALSE)
|
|
{
|
|
wsprintfA(szAutoTmpPath, "%s\\system32\\%s", szWindowsDirANSI, "autoexec.tmp");
|
|
if (FCheckForExistingFile(szAutoTmpPath) == FALSE)
|
|
{
|
|
// Per the old INF, skip the whole shebang.
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
pszAutoPath = szAutoTmpPath;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pszAutoPath = szAutoNTPath;
|
|
}
|
|
|
|
// At this point, we should have found at least one valid
|
|
// autoexec.nt or .tmp file. If not, we should have dropped out of the
|
|
// function
|
|
|
|
Assert(pszAutoPath);
|
|
|
|
pszRem1 = SzLoadStringPcch(_Module.GetResourceInstance(), IDS_AUTOEXEC_REM1, &iLength);
|
|
if (!pszRem1 || iLength == 0)
|
|
{
|
|
AssertSz(FALSE, "Failed to load STR_AUTOEXEC_REM from the resources");
|
|
|
|
TraceTag(ttidNWClientCfg,
|
|
"ERROR: Failed to load STR_AUTOEXEC_REM from the resources");
|
|
|
|
hr = E_FAIL;
|
|
goto Exit;
|
|
}
|
|
|
|
// Allocate memory for the demoted string.
|
|
pszaRem1MultiByte = (PSTR) MemAlloc(lstrlenW(pszRem1) + 1);
|
|
if (!pszaRem1MultiByte)
|
|
{
|
|
TraceTag(ttidNWClientCfg, "ERROR: Failed to alloc memory for demoted string");
|
|
hr = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
// Demote the loaded string to multibyte (single char)
|
|
WideCharToMultiByte(
|
|
CP_ACP, // ANSI code page
|
|
0, // flags for non-mapped character action
|
|
pszRem1, // source string
|
|
-1, // source string is NULL terminated
|
|
pszaRem1MultiByte, // destination string (multibyte)
|
|
lstrlenW(pszRem1) + 1, // size of destination string
|
|
NULL, // default char on non-mapped char
|
|
NULL); // return for default char mapping action
|
|
|
|
// Move the REM from the autoexec.nt
|
|
//
|
|
fResult = FMoveSzToEndOfFile(pszAutoPath, pszaRem1MultiByte);
|
|
if (!fResult)
|
|
{
|
|
// Traced in called function.
|
|
hr = E_FAIL;
|
|
goto Exit;
|
|
}
|
|
|
|
// Move the line that loads nw16
|
|
//
|
|
fResult = FMoveSzToEndOfFile(pszAutoPath, "lh %SystemRoot%\\system32\\nw16");
|
|
if (!fResult)
|
|
{
|
|
// Traced in called function.
|
|
hr = E_FAIL;
|
|
goto Exit;
|
|
}
|
|
|
|
// Move the line that loads vwipxspx
|
|
//
|
|
fResult = FMoveSzToEndOfFile(pszAutoPath, "lh %SystemRoot%\\system32\\vwipxspx");
|
|
if (!fResult)
|
|
{
|
|
// Traced in called function.
|
|
hr = E_FAIL;
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
MemFree(pszaRem1MultiByte);
|
|
|
|
TraceTag(ttidNWClientCfgFn, "<< HrMungeAutoexecNT");
|
|
TraceError("HrMungeAutoexecNT", hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrAddNetWareToWOWKnownList
|
|
//
|
|
// Purpose: Add the netware.drv to the WOW "known DLLS" list.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK or valid Win32 error code.
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrAddNetWareToWOWKnownList()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> HrAddNetWareToWOWKnownList");
|
|
|
|
// Call the cool new AddString... function
|
|
//
|
|
hr = HrRegAddStringToSz(
|
|
L"netware.drv",
|
|
HKEY_LOCAL_MACHINE,
|
|
L"System\\CurrentControlSet\\Control\\WOW",
|
|
L"KnownDLLS",
|
|
L' ',
|
|
STRING_FLAG_ENSURE_AT_END,
|
|
0);
|
|
|
|
TraceTag(ttidNWClientCfgFn, "<< HrAddNetWareToWOWKnownList");
|
|
TraceError("HrAddNetWareToWOWKnownList", hr);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrRemoveNetWareFromWOWKnownList
|
|
//
|
|
// Purpose: Add the netware.drv to the WOW "known DLLS" list.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK or valid Win32 error code.
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrRemoveNetWareFromWOWKnownList()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> HrRemoveNetWareFromWOWKnownList");
|
|
|
|
// Call the cool new AddString... function
|
|
//
|
|
hr = HrRegRemoveStringFromSz(
|
|
L"netware.drv",
|
|
HKEY_LOCAL_MACHINE,
|
|
L"System\\CurrentControlSet\\Control\\WOW",
|
|
L"KnownDLLS",
|
|
L' ',
|
|
STRING_FLAG_REMOVE_SINGLE);
|
|
|
|
TraceTag(ttidNWClientCfgFn, "<< HrRemoveNetWareFromWOWKnownList");
|
|
TraceError("HrRemoveNetWareFromWOWKnownList", hr);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrUpdateLanmanSharedDrivesValue
|
|
//
|
|
// Purpose: If the LanmanServer service exists, make sure that they have the
|
|
// EnableSharedNetDrives value turned on.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK or valid Win32 error code.
|
|
//
|
|
// Author: jeffspr 24 Jun 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrUpdateLanmanSharedDrivesValue()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
const DWORD c_dwESNDValue = 1;
|
|
HKEY hkeyLMSP = NULL;
|
|
SERVER_INFO_1540 si1540 = {0};
|
|
NET_API_STATUS nas = ERROR_SUCCESS;
|
|
DWORD dwDisposition = 0;
|
|
|
|
TraceTag(ttidNWClientCfgFn, ">> HrUpdateLanmanSharedDrivesValue");
|
|
|
|
// Open the LanmanServer parameters key, if it exists. If it doesn't exist,
|
|
// it will still return S_OK, but the hkey will still be NULL.
|
|
//
|
|
hr = HrRegCreateKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
L"System\\CurrentControlSet\\Services\\LanmanServer\\Parameters",
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_SET_VALUE, // samDesired
|
|
NULL,
|
|
&hkeyLMSP,
|
|
&dwDisposition);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceTag(ttidNWClientCfgFn, "Failed to create/open the "
|
|
"LanmanServer\\Parameters key");
|
|
goto Exit;
|
|
}
|
|
|
|
Assert(hkeyLMSP);
|
|
|
|
hr = HrRegSetDword(
|
|
hkeyLMSP,
|
|
L"EnableSharedNetDrives",
|
|
c_dwESNDValue);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceTag(ttidNWClientCfgFn, "Failed to set the EnabledSharedNetDrives value in "
|
|
"HrUpdateLanmanSharedDrivesValue()");
|
|
goto Exit;
|
|
}
|
|
|
|
// Call the NetServerSetInfo with the Enable Shared Net Drives info (1540).
|
|
// This will allow this info to be set dynamically (so as not to require a
|
|
// restart of the "Server" service.
|
|
//
|
|
si1540.sv1540_enablesharednetdrives = TRUE;
|
|
|
|
// Set the server info for the EnableSharedDrives value. This will cause it to
|
|
// take effect if the service is running (and will do nothing if it is not).
|
|
//
|
|
nas = NetServerSetInfo(NULL, 1540, (LPBYTE) &si1540, NULL);
|
|
if (nas != NERR_Success)
|
|
{
|
|
// It's actually OK if this fails in one condition (0x842), because
|
|
// it WILL fail if the server service That's not a problem, because
|
|
// the value that I set in the registry above will be picked up the
|
|
// next time the server service starts.
|
|
//
|
|
// OK, cheesy, but I don't know the define, I just know that this is the
|
|
// right return code for our ignorable failure.
|
|
//
|
|
if (nas != 0x842)
|
|
{
|
|
AssertSz(nas == 0x842, "NetServerSetInfo failed for a reason other "
|
|
"than the service not running (which would have been ok)");
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
// Close the hkey, if it's open
|
|
RegSafeCloseKey(hkeyLMSP);
|
|
|
|
TraceTag(ttidNWClientCfgFn, "<< HrUpdateLanmanSharedDrivesValue");
|
|
TraceError("HrUpdateLanmanSharedDrivesValue()", hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrRenameNWDocFiles
|
|
//
|
|
// Purpose: On the server install, rename the nwdocgw.* files, since
|
|
// whether we're on CSNW or GSNW, the files are always called
|
|
// nwdoc.*
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: jeffspr 13 Jul 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrRenameNWDocFiles()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
WCHAR szWindowsDir[MAX_PATH+1];
|
|
WCHAR szSourceName[MAX_PATH+1];
|
|
WCHAR szTargetName[MAX_PATH+1];
|
|
|
|
// Get the windows directory
|
|
if (GetSystemWindowsDirectory(szWindowsDir, MAX_PATH) == 0)
|
|
{
|
|
TraceLastWin32Error("HrRenameNWDocFiles - Call to GetSystemWindowsDirectory");
|
|
hr = HrFromLastWin32Error();
|
|
goto Exit;
|
|
}
|
|
|
|
// Build the path for the first rename
|
|
//
|
|
wsprintfW(szSourceName, L"%s\\system32\\%s", szWindowsDir, c_szNwDocGWHelpName);
|
|
wsprintfW(szTargetName, L"%s\\system32\\%s", szWindowsDir, c_szNwDocHelpName);
|
|
|
|
// Rename the .HLP file. If this fails, no big deal.
|
|
//
|
|
if (!MoveFileEx(szSourceName, szTargetName, MOVEFILE_REPLACE_EXISTING))
|
|
{
|
|
// For debugging only.
|
|
//
|
|
DWORD dwLastError = GetLastError();
|
|
}
|
|
|
|
// Build the path for the second rename
|
|
//
|
|
wsprintfW(szSourceName, L"%s\\system32\\%s", szWindowsDir, c_szNwDocGWCNTName);
|
|
wsprintfW(szTargetName, L"%s\\system32\\%s", szWindowsDir, c_szNwDocCNTName);
|
|
|
|
// Rename the .CNT file. If this fails, no big deal.
|
|
//
|
|
if (!MoveFileEx(szSourceName, szTargetName, MOVEFILE_REPLACE_EXISTING))
|
|
{
|
|
// For debugging only.
|
|
//
|
|
DWORD dwLastError = GetLastError();
|
|
}
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|