Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1070 lines
34 KiB

//////////////////////////////////////////////////////////////////////////////
//
// File Name: fxocFile.cpp
//
// Abstract: This provides the file/directory routines used in the
// FaxOCM code base.
//
// Environment: Windows XP / User Mode
//
// Copyright (c) 2000 Microsoft Corporation
//
// Revision History:
//
// Date: Developer: Comments:
// ----- ---------- ---------
// 21-Mar-2000 Oren Rosenbloom (orenr) Created
//////////////////////////////////////////////////////////////////////////////
#include "faxocm.h"
#pragma hdrstop
#include <aclapi.h>
#define MAX_NUM_CHARS_INF_VALUE 255
//////////////////////// Static Function Prototypes //////////////////////////
static BOOL prv_ProcessDirectories(const TCHAR *pszSection,const TCHAR *pszDirAction);
static BOOL prv_ProcessShares(const TCHAR *pszSection,const TCHAR *pszShareAction);
static BOOL prv_SetFileSecurity(const FAX_FOLDER_Description& ffdFolder);
static DWORD prv_DoSetup(const TCHAR *pszSection,
BOOL bInstall,
const TCHAR *pszFnName,
HINF hInf,
const TCHAR *pszSourceRootPath,
HSPFILEQ hQueue,
DWORD dwFlags);
FAX_SHARE_Description::FAX_SHARE_Description()
: iPlatform(PRODUCT_SKU_UNKNOWN),
pSD(NULL)
{
}
FAX_SHARE_Description::~FAX_SHARE_Description()
{
if (pSD)
{
LocalFree(pSD);
}
}
FAX_FOLDER_Description::FAX_FOLDER_Description()
: iPlatform(PRODUCT_SKU_UNKNOWN),
pSD(NULL),
iAttributes(FILE_ATTRIBUTE_NORMAL)
{
}
FAX_FOLDER_Description::~FAX_FOLDER_Description()
{
if (pSD)
{
LocalFree(pSD);
}
}
///////////////////////////////
// fxocFile_Init
//
// Initialize this File queuing
// subsystem
//
// Params:
// - void
// Returns:
// - NO_ERROR on success
// - error code otherwise.
//
DWORD fxocFile_Init(void)
{
DWORD dwRes = NO_ERROR;
DBG_ENTER(_T("Init File Module"), dwRes);
return dwRes;
}
///////////////////////////////
// fxocFile_Term
//
// Terminate this file queuing subsystem.
//
// Params:
// - void.
// Returns:
// - NO_ERROR on success
// - error code otherwise.
//
DWORD fxocFile_Term(void)
{
DWORD dwRes = NO_ERROR;
DBG_ENTER(_T("Term File Module"), dwRes);
return dwRes;
}
///////////////////////////////
// fxocFile_Install
//
// Installs files listed in
// the INF setup file into their
// specified location.
//
// Params:
// - pszSubcomponentId
// - pszInstallSection - install section in INF file (e.g. Fax.CleanInstall)
// Returns:
// - NO_ERROR on success.
// - error code otherwise.
//
DWORD fxocFile_Install(const TCHAR *pszSubcomponentId,
const TCHAR *pszInstallSection)
{
HINF hInf = NULL;
HSPFILEQ hQueue = NULL;
DWORD dwReturn = NO_ERROR;
BOOL bSuccess = FALSE;
DBG_ENTER( _T("fxocFile_Install"),
dwReturn,
_T("%s - %s"),
pszSubcomponentId,
pszInstallSection);
if (pszInstallSection == NULL)
{
return ERROR_INVALID_PARAMETER;
}
// get the INF handle for our component inf file
hInf = faxocm_GetComponentInf();
// get the file queue handle
hQueue = faxocm_GetComponentFileQueue();
// unregister DLLs first, before a file might be deleted by the file copy below.
if (::SetupInstallFromInfSection(NULL,hInf,pszInstallSection,SPINST_UNREGSVR,NULL,NULL,0,NULL,NULL,NULL,NULL))
{
VERBOSE(DBG_MSG,
_T("Successfully processed SPINST_UNREGSVR from INF file, section '%s'"),
pszInstallSection);
}
else
{
dwReturn = GetLastError();
VERBOSE(SETUP_ERR,
_T("Failed to process SPINST_UNREGSVR, section '%s', dwReturn = 0x%lx"),
pszInstallSection,
dwReturn);
}
// unregister platform specific DLLs first - this can happen during an upgrade from XP Beta -> XP RC1 and XP RTM
dwReturn = fxocUtil_SearchAndExecute(pszInstallSection,INF_KEYWORD_UNREGISTER_DLL_PLATFORM,SPINST_UNREGSVR,NULL);
if (dwReturn == NO_ERROR)
{
VERBOSE(DBG_MSG,
_T("Successfully Unregistered Fax DLLs - platform dependent")
_T("from INF file, section '%s'"),
pszInstallSection);
}
else
{
VERBOSE(SETUP_ERR,
_T("Failed to Unregister Fax DLLs - platform dependent")
_T("from INF file, section '%s', dwReturn = 0x%lx"),
pszInstallSection,
dwReturn);
}
dwReturn = prv_DoSetup(pszInstallSection,
TRUE,
_T("fxocFile_Install"),
hInf,
NULL,
hQueue,
SP_COPY_NEWER);
// now attemp to install platform specific files
dwReturn = fxocUtil_SearchAndExecute(pszInstallSection,INF_KEYWORD_COPYFILES_PLATFORM,SP_COPY_NEWER,hQueue);
if (dwReturn == NO_ERROR)
{
VERBOSE(DBG_MSG,
_T("Successfully Queued Files - platform dependent")
_T("from INF file, section '%s'"),
pszInstallSection);
}
else
{
VERBOSE(SETUP_ERR,
_T("Failed to Queued Files - platform dependent")
_T("from INF file, section '%s', dwReturn = 0x%lx"),
pszInstallSection,
dwReturn);
}
return dwReturn;
}
///////////////////////////////
// fxocFile_Uninstall
//
// Uninstalls files listed in
// the INF setup file.
//
// Params:
// - pszSubcomponentId
// - pszUninstallSection - section in INF (e.g. Fax.Uninstall)
// Returns:
// - NO_ERROR on success.
// - error code otherwise.
//
DWORD fxocFile_Uninstall(const TCHAR *pszSubcomponentId,
const TCHAR *pszUninstallSection)
{
HINF hInf = NULL;
HSPFILEQ hQueue = NULL;
DWORD dwReturn = NO_ERROR;
BOOL bSuccess = FALSE;
DBG_ENTER( _T("fxocFile_Install"),
dwReturn,
_T("%s - %s"),
pszSubcomponentId,
pszUninstallSection);
if (pszUninstallSection == NULL)
{
return ERROR_INVALID_PARAMETER;
}
// get the INF handle for our component inf file
hInf = faxocm_GetComponentInf();
// get the file queue handle
hQueue = faxocm_GetComponentFileQueue();
// unregister all our DLLs first
if (::SetupInstallFromInfSection(NULL,hInf,pszUninstallSection,SPINST_UNREGSVR,NULL,NULL,0,NULL,NULL,NULL,NULL))
{
VERBOSE(DBG_MSG,
_T("Successfully processed SPINST_UNREGSVR from INF file, section '%s'"),
pszUninstallSection);
}
else
{
dwReturn = GetLastError();
VERBOSE(SETUP_ERR,
_T("Failed to process SPINST_UNREGSVR, section '%s', dwReturn = 0x%lx"),
pszUninstallSection,
dwReturn);
}
// Now delete the files.
// this function will uninstall if the section retrieved above
// contains the 'DelFiles' keyword.
dwReturn = prv_DoSetup(pszUninstallSection,
FALSE,
_T("fxocFile_Uninstall"),
hInf,
NULL,
hQueue,
0);
return dwReturn;
}
///////////////////////////////
// prv_DoSetup
//
// Generic routine to call the appropriate
// Setup API fn, depending on if we are installing
// or uninstalling.
//
// Params:
// - pszSection - section we are processing
// - bInstall - TRUE if installing, FALSE if uninstalling
// - pszFnName - name of calling fn (for debug)
// - hInf - handle to faxsetup.inf.
// - pszSourceRootPath - path we are installing from.
// - hQueue - handle to file queue given to us by OC Manager
// - dwFlags - flags to pass to setup API.
// Returns:
// - NO_ERROR on success.
// - error code otherwise.
//
static DWORD prv_DoSetup(const TCHAR *pszSection,
BOOL bInstall,
const TCHAR *pszFnName,
HINF hInf,
const TCHAR *pszSourceRootPath,
HSPFILEQ hQueue,
DWORD dwFlags)
{
DWORD dwReturn = NO_ERROR;
BOOL bSuccess = FALSE;
DBG_ENTER( _T("prv_DoSetup"),
dwReturn,
_T("%s - %s - %s"),
pszSection,
pszFnName,
pszSourceRootPath);
// this function will search the INF for the 'CopyFiles' keyword
// and copy all files referenced by it.
bSuccess = ::SetupInstallFilesFromInfSection(hInf,
NULL,
hQueue,
pszSection,
pszSourceRootPath,
dwFlags);
if (bSuccess)
{
VERBOSE(DBG_MSG,
_T("%s, Successfully queued files ")
_T("from Section: '%s'"),
pszFnName,
pszSection);
}
else
{
dwReturn = GetLastError();
VERBOSE(DBG_MSG,
_T("%s, Failed to queue files ")
_T("from Section: '%s', Error Code = 0x%lx"),
pszFnName,
pszSection,
dwReturn);
}
return dwReturn;
}
///////////////////////////////
// fxocFile_CalcDiskSpace
//
// Calculate the disk space requirements
// of fax. This is done by the Setup APIs
// based on the files we are copying and
// deleting as specified in faxsetup.inf.
//
// Params:
// - pszSubcomponentId
// - bIsBeingAdded - are we installing or uninstalling.
// - hDiskSpace - handle to diskspace abstraction.
// Returns:
// - NO_ERROR on success.
// - error code otherwise
//
DWORD fxocFile_CalcDiskSpace(const TCHAR *pszSubcomponentId,
BOOL bIsBeingAdded,
HDSKSPC hDiskSpace)
{
HINF hInf = faxocm_GetComponentInf();
DWORD dwReturn = NO_ERROR;
BOOL bSuccess = FALSE;
TCHAR szSectionToProcess[255 + 1];
DBG_ENTER( _T("fxocFile_CalcDiskSpace"),
dwReturn,
_T("%s"),
pszSubcomponentId);
if ((hInf == NULL) ||
(pszSubcomponentId == NULL))
{
return ERROR_INVALID_PARAMETER;
}
// since disk space calc needs to be consistent, select the clean install
// section for the disk space calculation section. This is a good
// estimate.
if (dwReturn == NO_ERROR)
{
dwReturn = fxocUtil_GetKeywordValue(pszSubcomponentId,
INF_KEYWORD_INSTALLTYPE_CLEAN,
szSectionToProcess,
sizeof(szSectionToProcess) / sizeof(TCHAR));
}
if (dwReturn == NO_ERROR)
{
if (bIsBeingAdded)
{
bSuccess = ::SetupAddInstallSectionToDiskSpaceList(
hDiskSpace,
hInf,
NULL,
szSectionToProcess,
0,
0);
}
else
{
bSuccess = ::SetupRemoveInstallSectionFromDiskSpaceList(
hDiskSpace,
hInf,
NULL,
szSectionToProcess,
0,
0);
}
if (!bSuccess)
{
dwReturn = GetLastError();
VERBOSE(SETUP_ERR,
_T("fxocFile_CalcDiskSpace, failed to calculate ")
_T("disk space, error code = 0x%lx"), dwReturn);
}
else
{
VERBOSE(DBG_MSG,
_T("fxocFile_CalcDiskSpace, ")
_T("SubComponentID: '%s', Section: '%s', ")
_T("bIsBeingAdded: '%lu', ")
_T("rc=0x%lx"), pszSubcomponentId, szSectionToProcess,
bIsBeingAdded,
dwReturn);
}
}
return dwReturn;
}
///////////////////////////////
// fxocFile_ProcessDirectories
//
// Create or Delete the directories
// in the given section,
//
// pszINFKeyword - INF_KEYWORD_DELDIR to delete the directories
// INF_KEYWORD_CREATEDIR to create the directories
//
DWORD fxocFile_ProcessDirectories(const TCHAR *pszSection, LPCTSTR pszINFKeyword)
{
DWORD dwReturn = NO_ERROR;
DBG_ENTER( _T("fxocFile_ProcessDirectories"),
dwReturn,
_T("%s"),
pszSection);
// delete or create (according to pszINFKeyword) all the shares specified in the
// INF section.
if (!prv_ProcessDirectories(pszSection,pszINFKeyword))
{
dwReturn = GetLastError();
VERBOSE(DBG_WARNING,_T("Problems deleting/creating directories.... [%s]"),pszINFKeyword);
}
return dwReturn;
}
///////////////////////////////
// fxocFile_ProcessShares
//
// Create and/or Delete shares
// directories/printers specfiied
// in the given section.
//
// Params:
// - pszSection - section containing the 'CreateShare'/'DelShare'
// keyword
// Returns:
// - NO_ERROR on success.
// - error code otherwise.
//
DWORD fxocFile_ProcessShares(const TCHAR *pszSection)
{
DWORD dwReturn = NO_ERROR;
DBG_ENTER( _T("fxocFile_ProcessShares"),
dwReturn,
_T("%s"),
pszSection);
// first, delete all the shares specified in the
// INF section.
if (!prv_ProcessShares(pszSection,INF_KEYWORD_DELSHARE))
{
VERBOSE(DBG_WARNING,_T("Problems deleting shares...."));
}
// next, create all the shares specified in the
// INF section.
if (!prv_ProcessShares(pszSection,INF_KEYWORD_CREATESHARE))
{
VERBOSE(DBG_WARNING,_T("Problems creating shares...."));
}
return dwReturn;
}
static BOOL prv_FillFolderDescriptionFromInf(const TCHAR *pszFolderSection,FAX_FOLDER_Description& fsdFolder)
{
INFCONTEXT Context;
BOOL bSuccess = TRUE;
HINF hInf = NULL;
TCHAR szStringSd[MAX_PATH*3] = {0};
DBG_ENTER( _T("prv_FillFolderDescriptionFromInf"),
bSuccess,
_T("%s"),
pszFolderSection);
hInf = faxocm_GetComponentInf();
memset(&Context, 0, sizeof(Context));
// get the Path line in the section.
if (!::SetupFindFirstLine(hInf,pszFolderSection,INF_KEYWORD_PATH,&Context))
{
VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_PATH,GetLastError());
return FALSE;
}
bSuccess = ::SetupGetStringField(&Context,1,fsdFolder.szPath,MAX_PATH,NULL);
if (!bSuccess)
{
VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_PATH,GetLastError());
return FALSE;
}
// get the Platform line in the section.
if (!::SetupFindFirstLine(hInf,pszFolderSection,INF_KEYWORD_PLATFORM,&Context))
{
VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_PLATFORM,GetLastError());
return FALSE;
}
bSuccess = ::SetupGetIntField(&Context, 1, &fsdFolder.iPlatform);
if (!bSuccess)
{
VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_PLATFORM,GetLastError());
return FALSE;
}
// get the attributes line if it exists.
if (::SetupFindFirstLine(hInf,pszFolderSection,INF_KEYWORD_ATTRIBUTES,&Context))
{
bSuccess = ::SetupGetIntField(&Context, 1, &fsdFolder.iAttributes);
if (!bSuccess)
{
VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_PLATFORM,GetLastError());
return FALSE;
}
}
else
{
VERBOSE( DBG_MSG,
_T("SetupFindFirstLine failed (%s) (ec=%d), ")
_T("this is an optional field assuming non-existant"),
INF_KEYWORD_ATTRIBUTES,
GetLastError());
}
// get the Security line in the section.
if (!::SetupFindFirstLine(hInf,pszFolderSection,INF_KEYWORD_SECURITY,&Context))
{
VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_SECURITY,GetLastError());
return FALSE;
}
bSuccess = ::SetupGetStringField(&Context,1,szStringSd,MAX_PATH,NULL);
if (!bSuccess)
{
VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_SECURITY,GetLastError());
return FALSE;
}
if (!ConvertStringSecurityDescriptorToSecurityDescriptor(szStringSd,SDDL_REVISION_1,&fsdFolder.pSD,NULL))
{
VERBOSE(SETUP_ERR,_T("ConvertStringSecurityDescriptorToSecurityDescriptor failed (%s) (ec=%d)"),szStringSd,GetLastError());
return FALSE;
}
return TRUE;
}
static BOOL prv_FillShareDescriptionFromInf(const TCHAR *pszShareSection,FAX_SHARE_Description& fsdShare)
{
INFCONTEXT Context;
BOOL bSuccess = TRUE;
HINF hInf = NULL;
TCHAR szStringSd[MAX_PATH*3] = {0};
DBG_ENTER( _T("prv_FillShareDescriptionFromInf"),
bSuccess,
_T("%s"),
pszShareSection);
hInf = faxocm_GetComponentInf();
memset(&Context, 0, sizeof(Context));
// get the Path line in the section.
if (!::SetupFindFirstLine(hInf,pszShareSection,INF_KEYWORD_PATH,&Context))
{
VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_PATH,GetLastError());
return FALSE;
}
bSuccess = ::SetupGetStringField(&Context,1,fsdShare.szPath,MAX_PATH,NULL);
if (!bSuccess)
{
VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_PATH,GetLastError());
return FALSE;
}
// get the Name line in the section.
if (!::SetupFindFirstLine(hInf,pszShareSection,INF_KEYWORD_NAME,&Context))
{
VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_NAME,GetLastError());
return FALSE;
}
bSuccess = ::SetupGetStringField(&Context,1,fsdShare.szName,MAX_PATH,NULL);
if (!bSuccess)
{
VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_NAME,GetLastError());
return FALSE;
}
// get the Comment line in the section.
if (!::SetupFindFirstLine(hInf,pszShareSection,INF_KEYWORD_COMMENT,&Context))
{
VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_COMMENT,GetLastError());
return FALSE;
}
bSuccess = ::SetupGetStringField(&Context,1,fsdShare.szComment,MAX_PATH,NULL);
if (!bSuccess)
{
VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_COMMENT,GetLastError());
return FALSE;
}
// get the Platform line in the section.
if (!::SetupFindFirstLine(hInf,pszShareSection,INF_KEYWORD_PLATFORM,&Context))
{
VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_PLATFORM,GetLastError());
return FALSE;
}
bSuccess = ::SetupGetIntField(&Context, 1, &fsdShare.iPlatform);
if (!bSuccess)
{
VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_PLATFORM,GetLastError());
return FALSE;
}
// get the Security line in the section.
if (!::SetupFindFirstLine(hInf,pszShareSection,INF_KEYWORD_SECURITY,&Context))
{
VERBOSE(SETUP_ERR,_T("SetupFindFirstLine failed (%s) (ec=%d)"),INF_KEYWORD_SECURITY,GetLastError());
return FALSE;
}
bSuccess = ::SetupGetStringField(&Context,1,szStringSd,MAX_PATH,NULL);
if (!bSuccess)
{
VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (%s) (ec=%d)"),INF_KEYWORD_SECURITY,GetLastError());
return FALSE;
}
if (!ConvertStringSecurityDescriptorToSecurityDescriptor(szStringSd,SDDL_REVISION_1,&fsdShare.pSD,NULL))
{
VERBOSE(SETUP_ERR,_T("ConvertStringSecurityDescriptorToSecurityDescriptor failed (%s) (ec=%d)"),szStringSd,GetLastError());
return FALSE;
}
return TRUE;
}
///////////////////////////////
// prv_ProcessDirectories
//
// Enumerates through the specified
// INF file in the specified section
// and gets the value of the next
// keyword 'CreateDir', or 'DelDir'
//
// This function looks for the following lines
// in the INF section
//
// CreateDir = [1st dir section],[2nd dir section],...
// or
// DelDir = [1st dir section],[2nd dir section],...
//
// [dir section] - is built in the following format:
// Path = <path to folder to create>
// Platform = <one of the PRODUCT_SKU_* below>
// Security = <DACL in string format>
//
// Params:
// - pszSection - section in the file to iterate through.
// - pszShareAction - one of INF_KEYWORD_CREATEDIR, INF_KEYWORD_DELDIR
//
// Returns:
// - TRUE if folders were processed successfully
// - FALSE otherwise
//
static BOOL prv_ProcessDirectories(const TCHAR *pszSection,const TCHAR *pszDirAction)
{
INFCONTEXT Context;
BOOL bSuccess = TRUE;
HINF hInf = NULL;
DWORD dwFieldCount = 0;
DWORD dwIndex = 0;
DWORD dwNumChars = MAX_PATH;
DWORD dwNumRequiredChars = 0;
TCHAR pszFolderSection[MAX_PATH] = {0};
DBG_ENTER( _T("prv_ProcessDirectories"),
bSuccess,
_T("%s - %s"),
pszSection,
pszDirAction);
if ((pszDirAction != INF_KEYWORD_CREATEDIR) &&
(pszDirAction != INF_KEYWORD_DELDIR))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (pszSection == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
hInf = faxocm_GetComponentInf();
memset(&Context, 0, sizeof(Context));
// get the first CreateDir or DelDir in the section.
bSuccess = ::SetupFindFirstLine(hInf,
pszSection,
pszDirAction,
&Context);
if (!bSuccess)
{
VERBOSE(DBG_WARNING,
_T("Did not find '%s' keyword in ")
_T("section '%s'. No action will be taken."),
pszDirAction,
pszSection);
return FALSE;
}
// Found the CreateDir or DelDir
// now let's see how many dirs to create/delete
dwFieldCount = SetupGetFieldCount(&Context);
if (dwFieldCount==0)
{
VERBOSE(SETUP_ERR,_T("SetupGetFieldCount failed (ec=%d)"),GetLastError());
return FALSE;
}
for (dwIndex=0; dwIndex<dwFieldCount; dwIndex++)
{
FAX_FOLDER_Description ffdFolder;
// iterate through fields, get the share section and process it.
bSuccess = ::SetupGetStringField(&Context, dwIndex+1, pszFolderSection, dwNumChars, &dwNumRequiredChars);
if (!bSuccess)
{
VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (ec=%d)"),GetLastError());
return FALSE;
}
// we have the share name in pszShareSection, fill out the FAX_SHARE_Description structure
if (!prv_FillFolderDescriptionFromInf(pszFolderSection,ffdFolder))
{
VERBOSE(SETUP_ERR,_T("prv_FillFolderDescriptionFromInf failed (ec=%d)"),GetLastError());
return FALSE;
}
// now we have all the data
// check if we should act on this platform...
if (!(ffdFolder.iPlatform & GetProductSKU()))
{
VERBOSE(DBG_MSG,_T("Folder should not be processed on this Platform, skipping..."));
continue;
}
if (pszDirAction == INF_KEYWORD_CREATEDIR)
{
// create the folder
bSuccess = MakeDirectory(ffdFolder.szPath);
if (!bSuccess)
{
DWORD dwReturn = ::GetLastError();
if (dwReturn != ERROR_ALREADY_EXISTS)
{
VERBOSE(SETUP_ERR,_T("MakeDirectory failed (ec=%d)"),dwReturn);
}
}
// set the folder's security and the files in it
if (!prv_SetFileSecurity(ffdFolder))
{
VERBOSE(SETUP_ERR, _T("prv_SetFileSecurity"), GetLastError());
}
// set the folder's attributes
if (ffdFolder.iAttributes!=FILE_ATTRIBUTE_NORMAL)
{
// no sense in setting normal attributes, since this is the default
// the attributes member is initialized to FILE_ATTRIBUTE_NORMAL so
// if we failed to read it from the INF it's still the same
// and if someone specifies it in the INF it'll be set by default.
DWORD dwFileAttributes = GetFileAttributes(ffdFolder.szPath);
if (dwFileAttributes!=-1)
{
dwFileAttributes |= ffdFolder.iAttributes;
if (!SetFileAttributes(ffdFolder.szPath,dwFileAttributes))
{
VERBOSE(SETUP_ERR, TEXT("SetFileAttributes"), GetLastError());
}
}
else
{
VERBOSE(SETUP_ERR, TEXT("GetFileAttributes"), GetLastError());
}
}
}
else
{
// delete the directory
DeleteDirectory(ffdFolder.szPath);
}
}
return TRUE;
}
///////////////////////////////
// prv_ProcessShares
//
// Enumerates through the specified
// INF file in the specified section
// and gets the value of the next
// keyword 'CreateShare', or 'DelShare'
//
// This function looks for the following lines
// in the INF section
//
// CreateShare = [1st share section],[2nd share section],...
// or
// DelShare = [1st share section],[2nd share section],...
//
// [share section] - is built in the following format:
// Path = <path to folder on which share is created>
// Name = <name of share as it appears to the user>
// Comment = <share comment as it appears to the user>
// Platform = <one of the below platform specifiers>
// Security = <DACL in string format>
//
// Params:
// - pszSection - section in the file to iterate through.
// - pszShareAction - one of INF_KEYWORD_CREATESHARE, INF_KEYWORD_DELSHARE
//
// Returns:
// - TRUE if shares were processed successfully
// - FALSE otherwise
//
static BOOL prv_ProcessShares(const TCHAR *pszSection,const TCHAR *pszShareAction)
{
INFCONTEXT Context;
BOOL bSuccess = TRUE;
HINF hInf = NULL;
DWORD dwFieldCount = 0;
DWORD dwIndex = 0;
DWORD dwNumChars = MAX_PATH;
DWORD dwNumRequiredChars = 0;
TCHAR pszShareSection[MAX_PATH] = {0};
DBG_ENTER( _T("prv_ProcessShares"),
bSuccess,
_T("%s - %s"),
pszSection,
pszShareAction);
if ((pszShareAction != INF_KEYWORD_CREATESHARE) &&
(pszShareAction != INF_KEYWORD_DELSHARE))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (pszSection == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
hInf = faxocm_GetComponentInf();
memset(&Context, 0, sizeof(Context));
// get the first CreateShare or DelShare in the section.
bSuccess = ::SetupFindFirstLine(hInf,
pszSection,
pszShareAction,
&Context);
if (!bSuccess)
{
VERBOSE(DBG_WARNING,
_T("Did not find '%s' keyword in ")
_T("section '%s'. No action will be taken."),
pszShareAction,
pszSection);
return FALSE;
}
// Found the CreateShare or DelShare.
// now let's see how many shares to create/delete
dwFieldCount = SetupGetFieldCount(&Context);
if (dwFieldCount==0)
{
VERBOSE(SETUP_ERR,_T("SetupGetFieldCount failed (ec=%d)"),GetLastError());
return FALSE;
}
for (dwIndex=0; dwIndex<dwFieldCount; dwIndex++)
{
FAX_SHARE_Description fsdShare;
// iterate through fields, get the share section and process it.
bSuccess = ::SetupGetStringField(&Context, dwIndex+1, pszShareSection, dwNumChars, &dwNumRequiredChars);
if (!bSuccess)
{
VERBOSE(SETUP_ERR,_T("SetupGetStringField failed (ec=%d)"),GetLastError());
return FALSE;
}
// we have the share name in pszShareSection, fill out the FAX_SHARE_Description structure
if (!prv_FillShareDescriptionFromInf(pszShareSection,fsdShare))
{
VERBOSE(SETUP_ERR,_T("prv_FillShareDescriptionFromInf failed (ec=%d)"),GetLastError());
return FALSE;
}
// now we have all the data
// check if we should act on this platform...
if (!(fsdShare.iPlatform & GetProductSKU()))
{
VERBOSE(DBG_MSG,_T("Share should not be processed on this Platform, skipping..."));
continue;
}
if (pszShareAction == INF_KEYWORD_CREATESHARE)
{
// create the share...
bSuccess = fxocUtil_CreateNetworkShare(&fsdShare);
if (!bSuccess)
{
VERBOSE(SETUP_ERR,
_T("Failed to create share name '%s', path '%s', ")
_T("comment '%s', rc=0x%lx"),
fsdShare.szName,
fsdShare.szPath,
fsdShare.szComment,
GetLastError());
}
}
else
{
// delete the share..
bSuccess = fxocUtil_DeleteNetworkShare(fsdShare.szName);
if (!bSuccess)
{
VERBOSE(SETUP_ERR,
_T("Failed to delete share name '%s', ")
_T("rc=0x%lx"),
fsdShare.szPath,
GetLastError());
}
}
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////
// Function:
// prv_SetFileSecurity
//
// Purpose:
// Secure a folder and set the ACL on all the files contained in it
//
// Params:
// FAX_FOLDER_Description ffdFolder - folder to secure
//
// Return Value:
// TRUE - in case of success
// FALSE - otherwise
//
// Author:
// Mooly Beery (MoolyB) 22-May-2002
///////////////////////////////////////////////////////////////////////////////////////
static BOOL prv_SetFileSecurity(const FAX_FOLDER_Description& ffFolder)
{
BOOL bRet = TRUE;
BOOL bDaclPresent = TRUE;
BOOL bDaclDefaulted = TRUE;
PACL pDacl = NULL;
DWORD dwRet = ERROR_SUCCESS;
HANDLE hFolder = INVALID_HANDLE_VALUE;
DBG_ENTER(_T("prv_SetFileSecurity"),bRet);
hFolder = CreateFile( ffFolder.szPath,
GENERIC_WRITE | WRITE_DAC,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if (hFolder==INVALID_HANDLE_VALUE)
{
VERBOSE(SETUP_ERR,_T("CreateFile failed (ec=%d)"),GetLastError());
bRet = FALSE;
goto exit;
}
bRet = GetSecurityDescriptorDacl( ffFolder.pSD,
&bDaclPresent,
&pDacl,
&bDaclDefaulted);
if (!bRet)
{
VERBOSE(SETUP_ERR,_T("GetSecurityDescriptorDacl failed (ec=%d)"),GetLastError());
bRet = FALSE;
goto exit;
}
if (!bDaclPresent)
{
VERBOSE(SETUP_ERR,_T("Security Descriptor does not contain a DACL"));
bRet = FALSE;
goto exit;
}
dwRet = SetSecurityInfo(hFolder,
SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
NULL,
NULL,
pDacl,
NULL);
if (dwRet!=ERROR_SUCCESS)
{
VERBOSE(SETUP_ERR,_T("SetSecurityInfo failed (ec=%d)"),GetLastError());
bRet = FALSE;
goto exit;
}
exit:
if (hFolder)
{
CloseHandle(hFolder);
}
return bRet;
}
// eof