835 lines
23 KiB
C
835 lines
23 KiB
C
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Copyright (c) 1997-1999 Microsoft Corporation
|
||
|
// All rights reserved.
|
||
|
//
|
||
|
// File Name:
|
||
|
// distfold.c
|
||
|
//
|
||
|
// Description:
|
||
|
// This file contains the dialog proc for the IDD_DISTFOLD page.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include "pch.h"
|
||
|
#include "resource.h"
|
||
|
#include <lm.h>
|
||
|
#include <winnetwk.h>
|
||
|
|
||
|
static TCHAR *StrSelectDistFolder;
|
||
|
static TCHAR *StrWindowsDistibFolder;
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: OnSetActiveDistFolder
|
||
|
//
|
||
|
// Purpose: Called when the page is about to display.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
VOID
|
||
|
OnSetActiveDistFolder(HWND hwnd)
|
||
|
{
|
||
|
SetDlgItemText(hwnd, IDT_DISTFOLDER, WizGlobals.DistFolder);
|
||
|
SetDlgItemText(hwnd, IDT_SHARENAME, WizGlobals.DistShareName);
|
||
|
|
||
|
WIZ_BUTTONS(hwnd, PSWIZB_BACK | PSWIZB_NEXT);
|
||
|
}
|
||
|
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ConvertRelativePathToUncPath
|
||
|
//
|
||
|
// Purpose: If the path is a local path or a network path, it is converted
|
||
|
// to its UNC equivalent. If the path is already a UNC path then
|
||
|
// it is just copied and returned. The output variable
|
||
|
// UncDistFolder is assumed to be of MAX_PATH length.
|
||
|
//
|
||
|
// Arguments:
|
||
|
|
||
|
//
|
||
|
// Returns: BOOL
|
||
|
// TRUE - on success,
|
||
|
// FALSE - on failure
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL
|
||
|
ConvertRelativePathToUncPath( IN const TCHAR *szRelativePath,
|
||
|
OUT TCHAR *UncDistFolder,
|
||
|
IN DWORD cbSize) {
|
||
|
|
||
|
TCHAR szLocalName[MAX_PATH];
|
||
|
TCHAR szDistribFolderDirPath[MAX_PATH];
|
||
|
TCHAR szUncPath[MAX_PATH];
|
||
|
const TCHAR *pDirString;
|
||
|
DWORD dwReturnValue;
|
||
|
DWORD dwSize;
|
||
|
HRESULT hrPrintf;
|
||
|
|
||
|
//
|
||
|
// Check and see if it is already a UNC Path, just checking to see if it
|
||
|
// begins with a \
|
||
|
//
|
||
|
if( szRelativePath[0] == _T('\\') ) {
|
||
|
|
||
|
lstrcpyn( UncDistFolder, szRelativePath, cbSize );
|
||
|
|
||
|
return( TRUE );
|
||
|
|
||
|
}
|
||
|
|
||
|
if( IsPathOnLocalDiskDrive( szRelativePath ) )
|
||
|
{
|
||
|
|
||
|
const TCHAR *pDirPath;
|
||
|
TCHAR szLocalComputerName[MAX_COMPUTERNAME_LENGTH + 1];
|
||
|
HRESULT hrCat;
|
||
|
|
||
|
dwSize = MAX_COMPUTERNAME_LENGTH + 1;
|
||
|
|
||
|
if( ! GetComputerName( szLocalComputerName, &dwSize ) )
|
||
|
{
|
||
|
ReportErrorId( NULL,
|
||
|
MSGTYPE_ERR | MSGTYPE_WIN32,
|
||
|
IDS_ERR_CANNOT_GET_LOCAL_COMPNAME );
|
||
|
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
hrPrintf=StringCchPrintf( UncDistFolder, cbSize, _T("\\\\%s\\"), szLocalComputerName );
|
||
|
|
||
|
pDirPath = szRelativePath;
|
||
|
|
||
|
//
|
||
|
// Set the dir path to just past the first \
|
||
|
//
|
||
|
pDirPath = pDirPath + 3;
|
||
|
|
||
|
hrCat=StringCchCat( UncDistFolder, cbSize, pDirPath );
|
||
|
|
||
|
return( TRUE );
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
hrPrintf=StringCchPrintf( szLocalName, AS(szLocalName), _T("%c:"), szRelativePath[0] );
|
||
|
|
||
|
pDirString = szRelativePath + 3;
|
||
|
|
||
|
lstrcpyn( szDistribFolderDirPath, pDirString, AS(szDistribFolderDirPath) );
|
||
|
|
||
|
dwSize = StrBuffSize( szUncPath );
|
||
|
|
||
|
dwReturnValue = WNetGetConnection( szLocalName, szUncPath, &dwSize );
|
||
|
|
||
|
|
||
|
if( dwReturnValue == NO_ERROR ) {
|
||
|
|
||
|
lstrcpyn( UncDistFolder, szUncPath, cbSize );
|
||
|
|
||
|
// Note:ConcatenatePaths will truncate to avoid buffer overrun
|
||
|
ConcatenatePaths( UncDistFolder,
|
||
|
szDistribFolderDirPath,
|
||
|
NULL );
|
||
|
|
||
|
return( TRUE );
|
||
|
|
||
|
}
|
||
|
else if( dwReturnValue == ERROR_BAD_DEVICE ) {
|
||
|
|
||
|
ReportErrorId( NULL,
|
||
|
MSGTYPE_ERR,
|
||
|
IDS_ERR_NETWORK_BAD_DEVICE );
|
||
|
|
||
|
}
|
||
|
else if( dwReturnValue == ERROR_NOT_CONNECTED ) {
|
||
|
|
||
|
ReportErrorId( NULL,
|
||
|
MSGTYPE_ERR,
|
||
|
IDS_ERR_NETWORK_NOT_CONNECTED );
|
||
|
|
||
|
}
|
||
|
else if( dwReturnValue == ERROR_CONNECTION_UNAVAIL ) {
|
||
|
|
||
|
ReportErrorId( NULL,
|
||
|
MSGTYPE_ERR,
|
||
|
IDS_ERR_NETWORK_CONNECTION_UNAVAIL );
|
||
|
|
||
|
}
|
||
|
else if( dwReturnValue == ERROR_NO_NETWORK ) {
|
||
|
|
||
|
ReportErrorId( NULL,
|
||
|
MSGTYPE_ERR,
|
||
|
IDS_ERR_NETWORK_NO_NETWORK );
|
||
|
|
||
|
}
|
||
|
else if( dwReturnValue == ERROR_NO_NET_OR_BAD_PATH ) {
|
||
|
|
||
|
ReportErrorId( NULL,
|
||
|
MSGTYPE_ERR,
|
||
|
IDS_ERR_NETWORK_NO_NETWORK );
|
||
|
|
||
|
}
|
||
|
else if( dwReturnValue == ERROR_EXTENDED_ERROR ) {
|
||
|
|
||
|
TCHAR szErrorString[MAX_STRING_LEN];
|
||
|
TCHAR szProviderName[MAX_STRING_LEN];
|
||
|
TCHAR szErrorCode[MAX_STRING_LEN];
|
||
|
DWORD dwErrorCode;
|
||
|
DWORD dwErrorSize = StrBuffSize( szErrorString );
|
||
|
DWORD dwProviderSize = StrBuffSize( szProviderName );
|
||
|
|
||
|
WNetGetLastError( &dwErrorCode,
|
||
|
szErrorString,
|
||
|
dwErrorSize,
|
||
|
szProviderName,
|
||
|
dwProviderSize );
|
||
|
|
||
|
_itot( dwErrorCode, szErrorCode, 10 );
|
||
|
|
||
|
ReportErrorId( NULL,
|
||
|
MSGTYPE_ERR,
|
||
|
IDS_ERR_NETWORK_EXTENDED_ERROR,
|
||
|
szProviderName,
|
||
|
szErrorCode,
|
||
|
szErrorString );
|
||
|
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
//
|
||
|
// Unknown error
|
||
|
//
|
||
|
ReportErrorId( NULL,
|
||
|
MSGTYPE_ERR,
|
||
|
IDS_ERR_NETWORK_UNKNOWN_ERROR );
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
return( FALSE );
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// NTRAID#NTBUG9-551874-2002/02/27-stelo,swamip - CreateDistFolder, ShareTheDistFolder should use the code from OEM mode, reduce attack surface
|
||
|
//
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CreateDistFolder
|
||
|
//
|
||
|
// Purpose: Creates the distribution folder and reports any error.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// HWND hwnd - current window
|
||
|
//
|
||
|
// Returns:
|
||
|
// TRUE - all is ok
|
||
|
// FALSE - the error was reported, stay on this page
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
BOOL
|
||
|
CreateDistFolder(HWND hwnd)
|
||
|
{
|
||
|
//
|
||
|
// Don't just CreateDir in case user says d:\foo\bar\fud and 'foo'
|
||
|
// doesn't exist. We want to make foo and bar and fud for the user.
|
||
|
//
|
||
|
// On the other hand, if d:\foo\bar\fud already exists, we want to
|
||
|
// report an error, because the user explicitly said "New Folder"
|
||
|
// on the dialog.
|
||
|
//
|
||
|
// So, check if it's there first, then just go silently make everything
|
||
|
// needed if it doesn't exist. EnsureDirExists() will be silent in
|
||
|
// the case that d:\foo\bar\fud already exists.
|
||
|
//
|
||
|
|
||
|
if ( DoesPathExist(WizGlobals.DistFolder) ) {
|
||
|
|
||
|
UINT iRet;
|
||
|
|
||
|
iRet = ReportErrorId(hwnd,
|
||
|
MSGTYPE_YESNO,
|
||
|
IDS_ERR_DISTFOLD_EXISTS,
|
||
|
WizGlobals.DistFolder);
|
||
|
|
||
|
if ( iRet != IDYES )
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if ( ! EnsureDirExists(WizGlobals.DistFolder) ) {
|
||
|
ReportErrorId(hwnd,
|
||
|
MSGTYPE_ERR | MSGTYPE_WIN32,
|
||
|
IDS_ERR_CREATING_DISTFOLD,
|
||
|
WizGlobals.DistFolder);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CheckDistFolder
|
||
|
//
|
||
|
// Purpose: This function is called only by OnWizNextDistFolder. It
|
||
|
// assumes that WizGlobals.DistFolder is up to date. We
|
||
|
// create a folder or check if one exists as the user asks.
|
||
|
//
|
||
|
// Returns:
|
||
|
// FALSE - Problems, don't let wizard proceed
|
||
|
// TRUE - All is cool, go to the next page
|
||
|
//
|
||
|
// Notes:
|
||
|
// - This routine directly reports any errors and prompts the
|
||
|
// user as needed.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
BOOL
|
||
|
CheckDistFolder(HWND hwnd)
|
||
|
{
|
||
|
|
||
|
TCHAR PathBuffer[MAX_PATH];
|
||
|
|
||
|
//
|
||
|
// If user selected a file instead of a folder, trap that now, (just
|
||
|
// for a more informative error message).
|
||
|
//
|
||
|
|
||
|
if ( DoesFileExist(WizGlobals.DistFolder) ) {
|
||
|
ReportErrorId(hwnd,
|
||
|
MSGTYPE_ERR,
|
||
|
IDS_ERR_FOLDER_IS_FILE,
|
||
|
WizGlobals.DistFolder);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if ( ! WizGlobals.bCreateNewDistFolder ) {
|
||
|
|
||
|
//
|
||
|
// We're trying to edit an existing distfolder. Popup if
|
||
|
//
|
||
|
// 1. It doesn't exist OR
|
||
|
// 2. Can't find dosnet.inf
|
||
|
//
|
||
|
// In the case of #1, make user change path or radio button.
|
||
|
// In the case of #2, let user edit it anyway via YES/NO popup.
|
||
|
//
|
||
|
|
||
|
if ( ! DoesFolderExist(WizGlobals.DistFolder) ) {
|
||
|
ReportErrorId(hwnd,
|
||
|
MSGTYPE_ERR,
|
||
|
IDS_ERR_FOLDER_NOT_EXIST,
|
||
|
WizGlobals.DistFolder);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If dosnet.inf doesn't exist, this isn't a distribution folder.
|
||
|
// Note, this is a really minimal check.
|
||
|
//
|
||
|
|
||
|
lstrcpyn(PathBuffer, WizGlobals.DistFolder, AS(PathBuffer));
|
||
|
ConcatenatePaths(PathBuffer, WizGlobals.Architecture, _T("dosnet.inf"), NULL);
|
||
|
|
||
|
if ( ! DoesFileExist(PathBuffer) ) {
|
||
|
|
||
|
UINT iRet;
|
||
|
|
||
|
iRet = ReportErrorId(
|
||
|
hwnd,
|
||
|
MSGTYPE_YESNO,
|
||
|
IDS_ERR_NOT_VALID_DISTFOLD,
|
||
|
WizGlobals.DistFolder);
|
||
|
|
||
|
if ( iRet != IDYES )
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
//
|
||
|
// We're creating a new distfolder. Go do the work.
|
||
|
//
|
||
|
|
||
|
if ( ! CreateDistFolder(hwnd) )
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ShareTheDistFolder
|
||
|
//
|
||
|
// Purpose: Called by the Next procedure to put up the share.
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
BOOL
|
||
|
ShareTheDistFolder(HWND hwnd, TCHAR *UncDistFolder)
|
||
|
{
|
||
|
LPTSTR pszServerPath;
|
||
|
TCHAR szServerName[MAX_PATH];
|
||
|
NET_API_STATUS nas;
|
||
|
SHARE_INFO_502 si502, *psi502;
|
||
|
BOOL bStatus = TRUE;
|
||
|
|
||
|
//
|
||
|
// Query this computer for info about the sharename the user
|
||
|
// just typed in.
|
||
|
//
|
||
|
|
||
|
nas = NetShareGetInfo(
|
||
|
NULL, // this computer
|
||
|
WizGlobals.DistShareName, // shrname
|
||
|
502, // amount of info
|
||
|
(LPBYTE*) &psi502); // the info (output)
|
||
|
|
||
|
//
|
||
|
// If this sharename is in use, we have to look at the directory that
|
||
|
// is being shared.
|
||
|
//
|
||
|
|
||
|
if ( nas == NERR_Success ) {
|
||
|
|
||
|
TCHAR szUncPath[MAX_PATH + 1];
|
||
|
|
||
|
//
|
||
|
// All is ok if this sharename is for the DistFolder
|
||
|
// We have to check both the relative and the UNC path
|
||
|
//
|
||
|
|
||
|
if( ! ConvertRelativePathToUncPath( psi502->shi502_path,
|
||
|
szUncPath,
|
||
|
AS(szUncPath)) )
|
||
|
{
|
||
|
lstrcpyn( szUncPath, psi502->shi502_path, AS(szUncPath) );
|
||
|
}
|
||
|
|
||
|
if ( lstrcmpi(WizGlobals.DistFolder, psi502->shi502_path) == 0 ||
|
||
|
lstrcmpi(WizGlobals.DistFolder, szUncPath) == 0 ) {
|
||
|
|
||
|
NetApiBufferFree(psi502);
|
||
|
return TRUE;
|
||
|
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// The sharename is in use, however, it's being used by a
|
||
|
// different directory. Report an error telling user to enter
|
||
|
// a different sharename.
|
||
|
//
|
||
|
|
||
|
ReportErrorId(hwnd,
|
||
|
MSGTYPE_ERR,
|
||
|
IDS_ERR_SHARENAME_INUSE,
|
||
|
WizGlobals.DistShareName);
|
||
|
NetApiBufferFree(psi502);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Put up the share
|
||
|
//
|
||
|
|
||
|
si502.shi502_netname = WizGlobals.DistShareName;
|
||
|
si502.shi502_type = STYPE_DISKTREE;
|
||
|
si502.shi502_remark = StrWindowsDistibFolder;
|
||
|
si502.shi502_permissions = 0;
|
||
|
si502.shi502_max_uses = SHI_USES_UNLIMITED;
|
||
|
si502.shi502_current_uses = 0;
|
||
|
si502.shi502_path = WizGlobals.DistFolder;
|
||
|
si502.shi502_passwd = NULL;
|
||
|
si502.shi502_reserved = 0;
|
||
|
si502.shi502_security_descriptor = NULL;
|
||
|
|
||
|
//
|
||
|
// Set the server path to NULL if it is on the local machine, or the
|
||
|
// computer name if it is on a remote machine
|
||
|
//
|
||
|
if( IsPathOnLocalDiskDrive(WizGlobals.DistFolder) ) {
|
||
|
pszServerPath = NULL;
|
||
|
}
|
||
|
else {
|
||
|
GetComputerNameFromUnc( UncDistFolder,
|
||
|
szServerName,
|
||
|
AS(szServerName));
|
||
|
|
||
|
pszServerPath = szServerName;
|
||
|
}
|
||
|
|
||
|
nas = NetShareAdd(pszServerPath,
|
||
|
502, // info-level
|
||
|
(LPBYTE) &si502, // info-buffer
|
||
|
NULL); // don't bother with parm
|
||
|
|
||
|
//
|
||
|
// If the NetShareAdd fails for some reason, report the error code
|
||
|
// to the user and give the user a chance to continue the wizard
|
||
|
// without enabling the share. The user might not have privelege
|
||
|
// to do this.
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// ISSUE-2002/02/27-stelo - The Net apis don't set GetLastError(). So how is one
|
||
|
// supposed to report the error message to the user, like
|
||
|
// 'access denied'???
|
||
|
//
|
||
|
// Run this test: Logon to an account without admin privelege.
|
||
|
// Now try to put up the share. I bet the error message is
|
||
|
// useless. This is a common scenario and should be addressed.
|
||
|
//
|
||
|
|
||
|
if ( nas != NERR_Success ) {
|
||
|
|
||
|
UINT iRet;
|
||
|
iRet = ReportErrorId(hwnd, MSGTYPE_YESNO, IDS_ERR_ENABLE_SHARE, nas);
|
||
|
|
||
|
if ( iRet != IDYES )
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: OnDistFolderInitDialog
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// Arguments: IN HWND hwnd - handle to the dialog
|
||
|
//
|
||
|
// Returns: VOID
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
static VOID
|
||
|
OnDistFolderInitDialog( IN HWND hwnd )
|
||
|
{
|
||
|
|
||
|
//
|
||
|
// Load text strings
|
||
|
//
|
||
|
|
||
|
StrSelectDistFolder = MyLoadString( IDS_SELECT_DISTRIB_FOLDER );
|
||
|
|
||
|
StrWindowsDistibFolder = MyLoadString( IDS_WINDOWS_DISTRIB_FOLDER );
|
||
|
|
||
|
//
|
||
|
// Set the text limit on the edit boxes
|
||
|
//
|
||
|
|
||
|
SendDlgItemMessage( hwnd,
|
||
|
IDT_DISTFOLDER,
|
||
|
EM_LIMITTEXT,
|
||
|
(WPARAM) MAX_DIST_FOLDER,
|
||
|
(LPARAM) 0 );
|
||
|
|
||
|
SendDlgItemMessage( hwnd,
|
||
|
IDT_SHARENAME,
|
||
|
EM_LIMITTEXT,
|
||
|
(WPARAM) MAX_SHARENAME,
|
||
|
(LPARAM) 0 );
|
||
|
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: OnWizNextDistFolder
|
||
|
//
|
||
|
// Purpose: Called when user pushes the NEXT button
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
BOOL
|
||
|
OnWizNextDistFolder(HWND hwnd)
|
||
|
{
|
||
|
BOOL bResult = TRUE;
|
||
|
|
||
|
//
|
||
|
// Get the control settings
|
||
|
//
|
||
|
|
||
|
GetDlgItemText(hwnd, IDT_DISTFOLDER, WizGlobals.DistFolder, MAX_DIST_FOLDER + 1);
|
||
|
|
||
|
GetDlgItemText(hwnd,
|
||
|
IDT_SHARENAME,
|
||
|
WizGlobals.DistShareName,
|
||
|
MAX_SHARENAME + 1);
|
||
|
|
||
|
// ISSUE-2002/02/27-stelo - need to check they entered a valid distrib folder here, i.e. that it is a valid path (local or UNC)
|
||
|
// which of these are valid?
|
||
|
//
|
||
|
// c
|
||
|
// c:
|
||
|
// c:\
|
||
|
// c\sdjf
|
||
|
// \somedir
|
||
|
// //somename
|
||
|
// asfdj
|
||
|
//
|
||
|
|
||
|
MyGetFullPath(WizGlobals.DistFolder);
|
||
|
|
||
|
//
|
||
|
// Make sure they filled in the edit boxes
|
||
|
//
|
||
|
if( WizGlobals.DistFolder[0] == _T('\0') ) {
|
||
|
ReportErrorId( hwnd, MSGTYPE_ERR, IDS_ERR_ENTER_DIST_FOLDER );
|
||
|
|
||
|
bResult = FALSE;
|
||
|
}
|
||
|
if( WizGlobals.DistShareName[0] == _T('\0') ) {
|
||
|
ReportErrorId( hwnd, MSGTYPE_ERR, IDS_ERR_ENTER_SHARENAME );
|
||
|
|
||
|
bResult = FALSE;
|
||
|
}
|
||
|
|
||
|
if( !bResult ) {
|
||
|
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, -1);
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
// ISSUE-2002/02/27-stelo - if they specified a network path, it may take a while for the
|
||
|
// connection to restore if they haven't used it in a while, we should probably
|
||
|
// do a pop-up here to tell them we are looking for it
|
||
|
|
||
|
//
|
||
|
// Do some checking for the dist fold, create it if necessary, etc...
|
||
|
//
|
||
|
|
||
|
if ( ! CheckDistFolder(hwnd) )
|
||
|
bResult = FALSE;
|
||
|
|
||
|
if( ! ConvertRelativePathToUncPath( WizGlobals.DistFolder,
|
||
|
WizGlobals.UncDistFolder,
|
||
|
AS(WizGlobals.UncDistFolder)) )
|
||
|
{
|
||
|
lstrcpyn( WizGlobals.UncDistFolder, WizGlobals.DistFolder, AS(WizGlobals.UncDistFolder) );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Share it out if we haven't already reported an error
|
||
|
//
|
||
|
|
||
|
if ( bResult ) {
|
||
|
|
||
|
if ( ! ShareTheDistFolder( hwnd, WizGlobals.UncDistFolder ) ) {
|
||
|
|
||
|
bResult = FALSE;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If OemFilesPath doesn't have a value, give it one.
|
||
|
//
|
||
|
|
||
|
if ( bResult && WizGlobals.OemFilesPath[0] == _T('\0') ) {
|
||
|
|
||
|
lstrcpyn( WizGlobals.OemFilesPath, WizGlobals.DistFolder, AS(WizGlobals.OemFilesPath) );
|
||
|
|
||
|
|
||
|
//Note:ConcatenatePaths truncates to avoid buffer overrun
|
||
|
ConcatenatePaths( WizGlobals.OemFilesPath,
|
||
|
WizGlobals.Architecture,
|
||
|
_T("$oem$"),
|
||
|
NULL );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Force creation of the $oem$ dir (if it doesn't exist already)
|
||
|
//
|
||
|
|
||
|
if ( bResult && ! EnsureDirExists(WizGlobals.OemFilesPath) ) {
|
||
|
ReportErrorId(hwnd,
|
||
|
MSGTYPE_ERR | MSGTYPE_WIN32,
|
||
|
IDS_ERR_CREATE_FOLDER,
|
||
|
WizGlobals.OemFilesPath);
|
||
|
|
||
|
bResult = FALSE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Route to the next wizard page
|
||
|
//
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: BrowseForDistFolder
|
||
|
//
|
||
|
// Purpose: Calls SHBrowseForFolder to allow user to browse for a
|
||
|
// distribution folder.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// HWND hwnd - owning window
|
||
|
// LPTSTR PathBuffer - MAX_PATH buffer to receive results
|
||
|
//
|
||
|
// Returns: BOOL - success
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
BOOL
|
||
|
BrowseForDistFolder(HWND hwnd, LPTSTR PathBuffer)
|
||
|
{
|
||
|
BROWSEINFO BrowseInf;
|
||
|
LPITEMIDLIST lpIdList;
|
||
|
UINT ulFlags = BIF_EDITBOX |
|
||
|
BIF_RETURNONLYFSDIRS;
|
||
|
|
||
|
BrowseInf.hwndOwner = hwnd;
|
||
|
BrowseInf.pidlRoot = NULL; // no initial root
|
||
|
BrowseInf.pszDisplayName = PathBuffer; // output
|
||
|
BrowseInf.lpszTitle = StrSelectDistFolder;
|
||
|
BrowseInf.ulFlags = ulFlags;
|
||
|
BrowseInf.lpfn = NULL;
|
||
|
BrowseInf.lParam = (LPARAM) 0;
|
||
|
BrowseInf.iImage = 0; // no image
|
||
|
|
||
|
lpIdList = SHBrowseForFolder(&BrowseInf);
|
||
|
|
||
|
//
|
||
|
// Get the pathname out of this idlist returned and free up the memory
|
||
|
//
|
||
|
|
||
|
if ( lpIdList == NULL )
|
||
|
return FALSE;
|
||
|
|
||
|
SHGetPathFromIDList(lpIdList, PathBuffer);
|
||
|
ILFreePriv(lpIdList);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: OnBrowseDistFolder
|
||
|
//
|
||
|
// Purpose: Called when user pushes the BROWSE button
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
VOID
|
||
|
OnBrowseDistFolder(HWND hwnd)
|
||
|
{
|
||
|
|
||
|
//
|
||
|
// NTRAID#NTBUG9-551874-2002/02/27-stelo,swamip - CreateDistFolder, ShareTheDistFolder should use the code from OEM mode, reduce attack surface
|
||
|
//
|
||
|
if ( BrowseForDistFolder(hwnd, WizGlobals.DistFolder) ) {
|
||
|
SendDlgItemMessage(hwnd,
|
||
|
IDT_DISTFOLDER,
|
||
|
WM_SETTEXT,
|
||
|
(WPARAM) MAX_PATH,
|
||
|
(LPARAM) WizGlobals.DistFolder);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: DlgDistFolderPage
|
||
|
//
|
||
|
// Purpose: This is the dialog procedure IDD_DISTFOLDER.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
INT_PTR CALLBACK
|
||
|
DlgDistFolderPage(
|
||
|
IN HWND hwnd,
|
||
|
IN UINT uMsg,
|
||
|
IN WPARAM wParam,
|
||
|
IN LPARAM lParam)
|
||
|
{
|
||
|
BOOL bStatus = TRUE;
|
||
|
|
||
|
switch (uMsg) {
|
||
|
|
||
|
case WM_INITDIALOG:
|
||
|
|
||
|
OnDistFolderInitDialog( hwnd );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
{
|
||
|
int nButtonId=LOWORD(wParam);
|
||
|
|
||
|
switch ( nButtonId ) {
|
||
|
|
||
|
case IDC_BROWSE:
|
||
|
|
||
|
if ( HIWORD(wParam) == BN_CLICKED )
|
||
|
OnBrowseDistFolder(hwnd);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
bStatus = FALSE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_NOTIFY:
|
||
|
{
|
||
|
LPNMHDR pnmh = (LPNMHDR)lParam;
|
||
|
|
||
|
// ISSUE-2002/02/27-stelo,swamip - should check for valid pointer (possible dereference)
|
||
|
//
|
||
|
switch( pnmh->code ) {
|
||
|
|
||
|
case PSN_QUERYCANCEL:
|
||
|
WIZ_CANCEL(hwnd);
|
||
|
break;
|
||
|
|
||
|
case PSN_SETACTIVE:
|
||
|
|
||
|
g_App.dwCurrentHelp = IDH_DIST_FLDR;
|
||
|
|
||
|
if ( (WizGlobals.iProductInstall != PRODUCT_UNATTENDED_INSTALL) ||
|
||
|
WizGlobals.bStandAloneScript)
|
||
|
WIZ_SKIP( hwnd );
|
||
|
else
|
||
|
OnSetActiveDistFolder(hwnd);
|
||
|
break;
|
||
|
|
||
|
case PSN_WIZBACK:
|
||
|
bStatus = FALSE;
|
||
|
break;
|
||
|
|
||
|
case PSN_WIZNEXT:
|
||
|
if ( !OnWizNextDistFolder(hwnd) )
|
||
|
WIZ_SKIP(hwnd);
|
||
|
else
|
||
|
bStatus = FALSE;
|
||
|
break;
|
||
|
|
||
|
case PSN_HELP:
|
||
|
WIZ_HELP();
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
bStatus = FALSE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
bStatus = FALSE;
|
||
|
break;
|
||
|
}
|
||
|
return bStatus;
|
||
|
}
|