Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1423 lines
37 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
fileq2.c
Abstract:
Setup file queue routines for enqueing copy operations.
Author:
Ted Miller (tedm) 15-Feb-1995
Revision History:
--*/
#include "setupntp.h"
#pragma hdrstop
PSOURCE_MEDIA_INFO
pSetupQueueSourceMedia(
IN OUT PSP_FILE_QUEUE Queue,
IN OUT PSP_FILE_QUEUE_NODE QueueNode,
IN LONG SourceRootStringId,
IN PCTSTR SourceDescription, OPTIONAL
IN PCTSTR SourceTagfile OPTIONAL
);
BOOL
pSetupQueueSingleCopy(
IN HSPFILEQ QueueHandle,
IN HINF InfHandle,
IN HINF ListInfHandle, OPTIONAL
IN PCTSTR SectionName, OPTIONAL
IN PCTSTR SourceRootPath,
IN PCTSTR SourceFilename,
IN PCTSTR TargetFilename,
IN DWORD CopyStyle
);
BOOL
pSetupGetSourceAllInfo(
IN HINF InfHandle,
IN UINT SourceId,
OUT PCTSTR *Description,
OUT PCTSTR *Tagfile,
OUT PCTSTR *RelativePath
);
//
// HACK ALERT!!! HACK HACK HACK!!!!
//
// There might be an override platform specified. If this is so,
// we will look for \i386, \mips, etc as the final component of the
// specified path when queuing files, and replace it with the
// override path. This is a TOTAL HACK.
//
PCTSTR PlatformPathOverride;
CRITICAL_SECTION PlatformPathOverrideCritSect;
VOID
pSetupInitPlatformPathOverrideSupport(
IN BOOL Init
)
{
if(Init) {
InitializeCriticalSection(&PlatformPathOverrideCritSect);
} else {
DeleteCriticalSection(&PlatformPathOverrideCritSect);
}
}
#ifdef UNICODE
//
// ANSI version
//
BOOL
SetupSetPlatformPathOverrideA(
IN PCSTR Override OPTIONAL
)
{
BOOL b;
DWORD rc;
PCWSTR p;
if(Override) {
rc = CaptureAndConvertAnsiArg(Override,&p);
} else {
p = NULL;
rc = NO_ERROR;
}
if(rc == NO_ERROR) {
b = SetupSetPlatformPathOverrideW(p);
rc = GetLastError();
} else {
b = FALSE;
}
if(p) {
MyFree(p);
}
SetLastError(rc);
return(b);
}
#else
//
// Unicode stub
//
BOOL
SetupSetPlatformPathOverrideW(
IN PCWSTR Override OPTIONAL
)
{
UNREFERENCED_PARAMETER(Override);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return(FALSE);
}
#endif
BOOL
SetupSetPlatformPathOverride(
IN PCTSTR Override OPTIONAL
)
{
BOOL b;
DWORD rc;
EnterCriticalSection(&PlatformPathOverrideCritSect);
if(Override) {
if(PlatformPathOverride) {
MyFree(PlatformPathOverride);
PlatformPathOverride = NULL;
}
try {
b = ((PlatformPathOverride = DuplicateString(Override)) != NULL);
if(!b) {
rc = ERROR_NOT_ENOUGH_MEMORY;
}
} except(EXCEPTION_EXECUTE_HANDLER) {
b = FALSE;
rc = ERROR_INVALID_PARAMETER;
}
} else {
if(PlatformPathOverride) {
MyFree(PlatformPathOverride);
PlatformPathOverride = NULL;
}
b = TRUE;
}
LeaveCriticalSection(&PlatformPathOverrideCritSect);
if(!b) {
SetLastError(rc);
}
return(b);
}
#ifdef UNICODE
//
// ANSI version
//
BOOL
SetupQueueCopyA(
IN HSPFILEQ QueueHandle,
IN PCSTR SourceRootPath,
IN PCSTR SourcePath, OPTIONAL
IN PCSTR SourceFilename,
IN PCSTR SourceDescription, OPTIONAL
IN PCSTR SourceTagfile, OPTIONAL
IN PCSTR TargetDirectory,
IN PCSTR TargetFilename, OPTIONAL
IN DWORD CopyStyle
)
{
PCWSTR sourceRootPath;
PCWSTR sourcePath;
PCWSTR sourceFilename;
PCWSTR sourceDescription;
PCWSTR sourceTagfile;
PCWSTR targetDirectory;
PCWSTR targetFilename;
BOOL b;
DWORD rc;
sourceRootPath = NULL;
sourcePath = NULL;
sourceFilename = NULL;
sourceDescription = NULL;
sourceTagfile = NULL;
targetDirectory = NULL;
targetFilename = NULL;
rc = NO_ERROR;
if(SourceRootPath) {
rc = CaptureAndConvertAnsiArg(SourceRootPath,&sourceRootPath);
}
if((rc == NO_ERROR) && SourcePath) {
rc = CaptureAndConvertAnsiArg(SourcePath,&sourcePath);
}
if((rc == NO_ERROR) && SourceFilename) {
rc = CaptureAndConvertAnsiArg(SourceFilename,&sourceFilename);
}
if((rc == NO_ERROR) && SourceDescription) {
rc = CaptureAndConvertAnsiArg(SourceDescription,&sourceDescription);
}
if((rc == NO_ERROR) && SourceTagfile) {
rc = CaptureAndConvertAnsiArg(SourceTagfile,&sourceTagfile);
}
if((rc == NO_ERROR) && TargetDirectory) {
rc = CaptureAndConvertAnsiArg(TargetDirectory,&targetDirectory);
}
if((rc == NO_ERROR) && TargetFilename) {
rc = CaptureAndConvertAnsiArg(TargetFilename,&targetFilename);
}
if(rc == NO_ERROR) {
b = SetupQueueCopyW(
QueueHandle,
sourceRootPath,
sourcePath,
sourceFilename,
sourceDescription,
sourceTagfile,
targetDirectory,
targetFilename,
CopyStyle
);
rc = GetLastError();
}
if(sourceRootPath) {
MyFree(sourceRootPath);
}
if(sourcePath) {
MyFree(sourcePath);
}
if(sourceFilename) {
MyFree(sourceFilename);
}
if(sourceDescription) {
MyFree(sourceDescription);
}
if(sourceTagfile) {
MyFree(sourceTagfile);
}
if(targetDirectory) {
MyFree(targetDirectory);
}
if(targetFilename) {
MyFree(targetFilename);
}
SetLastError(rc);
return(b);
}
#else
//
// Unicode stub
//
BOOL
SetupQueueCopyW(
IN HSPFILEQ QueueHandle,
IN PCWSTR SourceRootPath,
IN PCWSTR SourcePath, OPTIONAL
IN PCWSTR SourceFilename,
IN PCWSTR SourceDescription, OPTIONAL
IN PCWSTR SourceTagfile, OPTIONAL
IN PCWSTR TargetDirectory,
IN PCWSTR TargetFilename, OPTIONAL
IN DWORD CopyStyle
)
{
UNREFERENCED_PARAMETER(QueueHandle);
UNREFERENCED_PARAMETER(SourceRootPath);
UNREFERENCED_PARAMETER(SourcePath);
UNREFERENCED_PARAMETER(SourceFilename);
UNREFERENCED_PARAMETER(SourceDescription);
UNREFERENCED_PARAMETER(SourceTagfile);
UNREFERENCED_PARAMETER(TargetDirectory);
UNREFERENCED_PARAMETER(TargetFilename);
UNREFERENCED_PARAMETER(CopyStyle);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return(FALSE);
}
#endif
BOOL
SetupQueueCopy(
IN HSPFILEQ QueueHandle,
IN PCTSTR SourceRootPath,
IN PCTSTR SourcePath, OPTIONAL
IN PCTSTR SourceFilename,
IN PCTSTR SourceDescription, OPTIONAL
IN PCTSTR SourceTagfile, OPTIONAL
IN PCTSTR TargetDirectory,
IN PCTSTR TargetFilename, OPTIONAL
IN DWORD CopyStyle
)
/*++
Routine Description:
Place a copy operation on a setup file queue.
Arguments:
QueueHandle - supplies a handle to a setup file queue, as returned
by SetupOpenFileQueue.
SourceRootPath - Supplies the root of the source for this copy,
such as A:\ or \\FOO\BAR\BAZ.
SourcePath - if specified, supplies the path relative to SourceRootPath
where the file can be found.
SourceFilename - supplies the filename part of the file to be copied.
SourceDescription - if specified, supplies a description of the source
media, to be used during disk prompts.
SourceTagfile - if specified, supplies a tag file whose presence at
SourceRootPath indicates the presence of the source media.
If not specified, the file itself will be used as the tag file
if required (tagfiles are used only for removable media).
TargetDirectory - supplies the directory where the file is to be copied.
TargetFilename - if specified, supplies the name of the target file.
If not specified, the target file will have the same name as the source.
CopyStyle - supplies flags that control the behavior of the copy operation
for this file.
Return Value:
Boolean value indicating outcome. If FALSE, GetLastError() returns
extended error information.
--*/
{
PSP_FILE_QUEUE Queue;
PSP_FILE_QUEUE_NODE QueueNode,TempNode;
PSOURCE_MEDIA_INFO Source;
TCHAR TempBuffer[MAX_PATH];
PCTSTR LastPathPart;
PCTSTR p;
int Size;
DWORD d;
Queue = (PSP_FILE_QUEUE)QueueHandle;
d = NO_ERROR;
//
// Allocate a queue structure.
//
QueueNode = MyMalloc(sizeof(SP_FILE_QUEUE_NODE));
if(!QueueNode) {
d = ERROR_NOT_ENOUGH_MEMORY;
goto clean0;
}
//
// Operation is copy.
//
QueueNode->Operation = FILEOP_COPY;
QueueNode->InternalFlags = 0;
//
// HACK ALERT!!! HACK HACK HACK!!!!
//
// There might be an override platform specified. If this is so,
// we will look for \i386, \mips, etc as the final component of the
// specified path, and replace it with the override path.
// This is a TOTAL HACK.
//
EnterCriticalSection(&PlatformPathOverrideCritSect);
try {
if(PlatformPathOverride) {
p = SourcePath ? SourcePath : SourceRootPath;
if(LastPathPart = _tcsrchr(p,L'\\')) {
LastPathPart++;
} else {
LastPathPart = p;
}
#if defined(_ALPHA_)
if(!lstrcmpi(LastPathPart,TEXT("alpha"))) {
#elif defined(_MIPS_)
if(!lstrcmpi(LastPathPart,TEXT("mips"))) {
#elif defined(_PPC_)
if(!lstrcmpi(LastPathPart,TEXT("ppc"))) {
#elif defined(_X86_)
if(!lstrcmpi(LastPathPart,TEXT("x86")) || !lstrcmpi(LastPathPart,TEXT("i386"))) {
#endif
Size = LastPathPart - p;
Size = min(Size,MAX_PATH);
Size *= sizeof(TCHAR);
CopyMemory(TempBuffer,p,Size);
TempBuffer[Size/sizeof(TCHAR)] = 0;
//
// If the path was something like "mips" then TempBuffer
// will be empty and we don't want to introduce any extra
// backslashes.
//
if(*TempBuffer) {
ConcatenatePaths(TempBuffer,PlatformPathOverride,MAX_PATH,NULL);
} else {
lstrcpyn(TempBuffer,PlatformPathOverride,MAX_PATH);
}
if(SourcePath) {
SourcePath = TempBuffer;
} else {
SourceRootPath = TempBuffer;
}
}
}
} except(EXCEPTION_EXECUTE_HANDLER) {
d = ERROR_INVALID_PARAMETER;
}
LeaveCriticalSection(&PlatformPathOverrideCritSect);
if(d != NO_ERROR) {
goto clean1;
}
//
// NOTE: When adding the following strings to the string table, we cast away
// their CONST-ness to avoid a compiler warning. Since we are adding them
// case-sensitively, we are guaranteed they will not be modified.
//
try {
//
// Set up the source root path.
//
QueueNode->SourceRootPath = StringTableAddString(
Queue->StringTable,
(PTSTR)SourceRootPath,
STRTAB_CASE_SENSITIVE
);
if(QueueNode->SourceRootPath == -1) {
d = ERROR_NOT_ENOUGH_MEMORY;
}
//
// Set up the source path.
//
if(d == NO_ERROR) {
if(SourcePath) {
QueueNode->SourcePath = StringTableAddString(
Queue->StringTable,
(PTSTR)SourcePath,
STRTAB_CASE_SENSITIVE
);
if(QueueNode->SourcePath == -1) {
d = ERROR_NOT_ENOUGH_MEMORY;
}
} else {
QueueNode->SourcePath = -1;
}
}
//
// Set up the source filename.
//
if(d == NO_ERROR) {
QueueNode->SourceFilename = StringTableAddString(
Queue->StringTable,
(PTSTR)SourceFilename,
STRTAB_CASE_SENSITIVE
);
if(QueueNode->SourceFilename == -1) {
d = ERROR_NOT_ENOUGH_MEMORY;
}
}
//
// Set up the target directory.
//
if(d == NO_ERROR) {
QueueNode->TargetDirectory = StringTableAddString(
Queue->StringTable,
(PTSTR)TargetDirectory,
STRTAB_CASE_SENSITIVE
);
if(QueueNode->TargetDirectory == -1) {
d = ERROR_NOT_ENOUGH_MEMORY;
}
}
//
// Set up the target filename.
//
if(d == NO_ERROR) {
QueueNode->TargetFilename = StringTableAddString(
Queue->StringTable,
(PTSTR)(TargetFilename ? TargetFilename
: SourceFilename),
STRTAB_CASE_SENSITIVE
);
if(QueueNode->TargetFilename == -1) {
d = ERROR_NOT_ENOUGH_MEMORY;
}
}
} except(EXCEPTION_EXECUTE_HANDLER) {
d = ERROR_INVALID_PARAMETER;
}
if(d != NO_ERROR) {
goto clean1;
}
//
// Set up the copy style flags
//
QueueNode->StyleFlags = CopyStyle;
QueueNode->Next = NULL;
//
// Set up the source media.
//
try {
Source = pSetupQueueSourceMedia(
Queue,
QueueNode,
QueueNode->SourceRootPath,
SourceDescription,
SourceTagfile
);
if(!Source) {
d = ERROR_NOT_ENOUGH_MEMORY;
}
} except(EXCEPTION_EXECUTE_HANDLER) {
d = ERROR_INVALID_PARAMETER;
}
if(d != NO_ERROR) {
goto clean1;
}
//
// Link the node onto the end of the copy queue for this source media.
//
if(Source->CopyQueue) {
for(TempNode=Source->CopyQueue; TempNode->Next; TempNode=TempNode->Next) ;
TempNode->Next = QueueNode;
} else {
Source->CopyQueue = QueueNode;
}
Queue->CopyNodeCount++;
Source->CopyNodeCount++;
return(TRUE);
clean1:
MyFree(QueueNode);
clean0:
SetLastError(d);
return(FALSE);
}
#ifdef UNICODE
//
// ANSI version
//
BOOL
SetupQueueCopySectionA(
IN HSPFILEQ QueueHandle,
IN PCSTR SourceRootPath,
IN HINF InfHandle,
IN HINF ListInfHandle, OPTIONAL
IN PCSTR Section,
IN DWORD CopyStyle
)
{
PWSTR sourcerootpath;
PWSTR section;
DWORD rc;
BOOL b;
rc = CaptureAndConvertAnsiArg(SourceRootPath,&sourcerootpath);
if(rc != NO_ERROR) {
SetLastError(rc);
return(FALSE);
}
rc = CaptureAndConvertAnsiArg(Section,&section);
if(rc != NO_ERROR) {
MyFree(sourcerootpath);
SetLastError(rc);
return(FALSE);
}
b = SetupQueueCopySectionW(
QueueHandle,
sourcerootpath,
InfHandle,
ListInfHandle,
section,
CopyStyle
);
rc = GetLastError();
MyFree(sourcerootpath);
MyFree(section);
SetLastError(rc);
return(b);
}
#else
//
// Unicode stub
//
BOOL
SetupQueueCopySectionW(
IN HSPFILEQ QueueHandle,
IN PCWSTR SourceRootPath,
IN HINF InfHandle,
IN HINF ListInfHandle, OPTIONAL
IN PCWSTR Section,
IN DWORD CopyStyle
)
{
UNREFERENCED_PARAMETER(QueueHandle);
UNREFERENCED_PARAMETER(SourceRootPath);
UNREFERENCED_PARAMETER(InfHandle);
UNREFERENCED_PARAMETER(ListInfHandle);
UNREFERENCED_PARAMETER(Section);
UNREFERENCED_PARAMETER(CopyStyle);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return(FALSE);
}
#endif
BOOL
SetupQueueCopySection(
IN HSPFILEQ QueueHandle,
IN PCTSTR SourceRootPath,
IN HINF InfHandle,
IN HINF ListInfHandle, OPTIONAL
IN PCTSTR Section,
IN DWORD CopyStyle
)
/*++
Routine Description:
Queue an entire section in an inf file for copy. The section must be
in copy-section format and the inf file must contain [SourceDisksFiles]
and [SourceDisksNames] sections.
Arguments:
QueueHandle - supplies a handle to a setup file queue, as returned
by SetupOpenFileQueue.
SourceRootPath - supplies the root directory for the intended source.
This should be a sharepoint or a device root such as a:\ or g:\.
InfHandle - supplies a handle to an open inf file, that contains the
[SourceDisksFiles] and [SourceDisksNames] sections, and, if
ListInfHandle is not specified, contains the section names by Section.
This handle must be for a win95-style inf.
ListInfHandle - if specified, supplies a handle to an open inf file
containing the section to be queued for copy. Otherwise InfHandle
is assumed to contain the section.
Section - supplies the name of the section to be queued for copy.
CopyStyle - supplies flags that control the behavior of the copy operation
for this file.
Return Value:
Boolean value indicating outcome. If FALSE, GetLastError() returns
extended error information. Some of the files may have been queued.
--*/
{
BOOL b;
INFCONTEXT LineContext;
PCTSTR SourceFilename;
PCTSTR TargetFilename;
UINT Flags;
LONG LineCount;
//
// Note that there are no potential faults here so no try/excepts
// are necessary. pSetupQueueSingleCopy does all validation.
//
if(!ListInfHandle) {
ListInfHandle = InfHandle;
}
//
// Check for missing section
//
LineCount = SetupGetLineCount (ListInfHandle, Section);
if(LineCount == -1) {
SetLastError(ERROR_SECTION_NOT_FOUND);
return(FALSE);
}
//
// if section is empty, do nothing.
//
if(LineCount == 0) {
return(TRUE);
}
//
// The section has to exist and there has to be at least one line in it.
//
b = SetupFindFirstLine(ListInfHandle,Section,NULL,&LineContext);
if(!b) {
SetLastError(ERROR_SECTION_NOT_FOUND);
return(FALSE);
}
//
// Iterate every line in the section.
//
do {
//
// Get the target filename out of the line.
// Field 1 is the target so there must be one for the line to be valid.
//
TargetFilename = pSetupFilenameFromLine(&LineContext,FALSE);
if(!TargetFilename) {
SetLastError(ERROR_INVALID_DATA);
return(FALSE);
}
//
// Get source filename out of the line. If there is none, use
// the target name as the source name.
//
SourceFilename = pSetupFilenameFromLine(&LineContext,TRUE);
if(!SourceFilename || (*SourceFilename == 0)) {
SourceFilename = TargetFilename;
}
//
// If present, flags are field 3.
//
if(SetupGetIntField(&LineContext,4,(PINT)&Flags)) {
if(Flags & COPYFLG_WARN_IF_SKIP) {
CopyStyle |= SP_COPY_WARNIFSKIP;
}
if(Flags & COPYFLG_NOSKIP) {
CopyStyle |= SP_COPY_NOSKIP;
}
if(Flags & COPYFLG_NOVERSIONCHECK) {
CopyStyle &= ~SP_COPY_NEWER;
}
if(Flags & COPYFLG_FORCE_FILE_IN_USE) {
CopyStyle |= SP_COPY_FORCE_IN_USE;
CopyStyle |= SP_COPY_IN_USE_NEEDS_REBOOT;
}
if(Flags & COPYFLG_NO_OVERWRITE) {
CopyStyle |= SP_COPY_FORCE_NOOVERWRITE;
}
if(Flags & COPYFLG_NO_VERSION_DIALOG) {
CopyStyle |= SP_COPY_FORCE_NEWER;
}
if(Flags & COPYFLG_REPLACEONLY) {
CopyStyle |= SP_COPY_REPLACEONLY;
}
}
b = pSetupQueueSingleCopy(
QueueHandle,
InfHandle,
ListInfHandle,
Section,
SourceRootPath,
SourceFilename,
TargetFilename,
CopyStyle
);
if(!b) {
return(FALSE);
}
} while(SetupFindNextLine(&LineContext,&LineContext));
return(TRUE);
}
BOOL
pSetupQueueSingleCopy(
IN HSPFILEQ QueueHandle,
IN HINF InfHandle,
IN HINF ListInfHandle, OPTIONAL
IN PCTSTR SectionName, OPTIONAL
IN PCTSTR SourceRootPath,
IN PCTSTR SourceFilename,
IN PCTSTR TargetFilename,
IN DWORD CopyStyle
)
/*++
Routine Description:
Add a single file to the copy queue, using the default source media
and destination as specified in an inf file.
Arguments:
QueueHandle - supplies a handle to a setup file queue, as returned
by SetupOpenFileQueue.
InfHandle - supplies a handle to an open inf file, that contains the
[SourceDisksFiles] and [SourceDisksNames] sections.
This handle must be for a win95-style inf.
ListInfHandle - if specified, supplies handle to the inf in which
the file being copied appears (such as in a file copy list section).
If not specified, this is assumed to be the same inf as InfHandle.
SourceRootPath - supplies the root directory for the intended source.
This should be a sharepoint or a device root such as a:\ or g:\.
SourceFilename - supplies the filename of the source file. Filename part
only.
TargetFilename - supplies the filename of the target file. Filename part
only.
CopyStyle - supplies flags that control the behavior of the copy operation
for this file.
Return Value:
Boolean value indicating outcome. If FALSE, GetLastError() returns
extended error information.
--*/
{
BOOL b;
UINT SourceId;
DWORD SizeRequired;
PTSTR TargetDirectory;
PCTSTR SourceDescription,SourceTagfile,SourceRelativePath;
DWORD rc;
TCHAR FileSubdir[MAX_PATH];
TCHAR RelativePath[MAX_PATH];
if(!ListInfHandle) {
ListInfHandle = InfHandle;
}
//
// Determine the source disk id and subdir where the file is located.
//
b = SetupGetSourceFileLocation(
InfHandle,
NULL,
SourceFilename,
&SourceId,
FileSubdir,
MAX_PATH,
&rc
);
if(!b) {
//
// Assume file subdir is too big and is invalid.
// Try to fetch just the id and assume there is no subdir.
//
if(b = SetupGetSourceFileLocation(InfHandle,NULL,SourceFilename,&SourceId,NULL,0,NULL)) {
FileSubdir[0] = 0;
}
}
if(b) {
//
// Get information about the source. Need the tag file,
// description, and relative source path.
//
b = pSetupGetSourceAllInfo(
InfHandle,
SourceId,
&SourceDescription,
&SourceTagfile,
&SourceRelativePath
);
if(!b) {
//
// Last error already set.
//
return(FALSE);
}
} else {
//
// Assume there is no SourceDisksFiles section and fake it as best we can.
// Assume the media has a description of "Unknown," set the source path to
// the source root if there is one, and assume no tag file.
//
FileSubdir[0] = 0;
SourceDescription = NULL;
SourceTagfile = NULL;
SourceRelativePath = NULL;
}
//
// Determine the target path for the file.
//
if(b = SetupGetTargetPath(ListInfHandle,NULL,SectionName,NULL,0,&SizeRequired)) {
if(TargetDirectory = MyMalloc(SizeRequired*sizeof(TCHAR))) {
if(b = SetupGetTargetPath(ListInfHandle,NULL,SectionName,TargetDirectory,SizeRequired,NULL)) {
//
// Append the source relative path and the file subdir.
//
if(SourceRelativePath) {
lstrcpyn(RelativePath,SourceRelativePath,MAX_PATH);
if(FileSubdir[0]) {
ConcatenatePaths(RelativePath,FileSubdir,MAX_PATH,NULL);
}
} else {
RelativePath[0] = 0;
}
//
// Add to queue.
//
b = SetupQueueCopy(
QueueHandle,
SourceRootPath,
RelativePath,
SourceFilename,
SourceDescription,
SourceTagfile,
TargetDirectory,
TargetFilename,
CopyStyle
);
rc = GetLastError();
}
MyFree(TargetDirectory);
} else {
rc = ERROR_NOT_ENOUGH_MEMORY;
}
} else {
rc = GetLastError();
}
if(SourceDescription) {
MyFree(SourceDescription);
}
if(SourceTagfile) {
MyFree(SourceTagfile);
}
if(SourceRelativePath) {
MyFree(SourceRelativePath);
}
if(!b) {
SetLastError(rc);
}
return(b);
}
#ifdef UNICODE
//
// ANSI version
//
BOOL
SetupQueueDefaultCopyA(
IN HSPFILEQ QueueHandle,
IN HINF InfHandle,
IN PCSTR SourceRootPath,
IN PCSTR SourceFilename,
IN PCSTR TargetFilename,
IN DWORD CopyStyle
)
{
PWSTR sourcerootpath;
PWSTR sourcefilename;
PWSTR targetfilename;
DWORD rc;
BOOL b;
b = FALSE;
rc = CaptureAndConvertAnsiArg(SourceRootPath,&sourcerootpath);
if(rc == NO_ERROR) {
rc = CaptureAndConvertAnsiArg(SourceFilename,&sourcefilename);
if(rc == NO_ERROR) {
rc = CaptureAndConvertAnsiArg(TargetFilename,&targetfilename);
if(rc == NO_ERROR) {
b = SetupQueueDefaultCopyW(
QueueHandle,
InfHandle,
sourcerootpath,
sourcefilename,
targetfilename,
CopyStyle
);
rc = GetLastError();
MyFree(targetfilename);
}
MyFree(sourcefilename);
}
MyFree(sourcerootpath);
}
SetLastError(rc);
return(b);
}
#else
//
// Unicode stub
//
BOOL
SetupQueueDefaultCopyW(
IN HSPFILEQ QueueHandle,
IN HINF InfHandle,
IN PCWSTR SourceRootPath,
IN PCWSTR SourceFilename,
IN PCWSTR TargetFilename,
IN DWORD CopyStyle
)
{
UNREFERENCED_PARAMETER(QueueHandle);
UNREFERENCED_PARAMETER(InfHandle);
UNREFERENCED_PARAMETER(SourceRootPath);
UNREFERENCED_PARAMETER(SourceFilename);
UNREFERENCED_PARAMETER(TargetFilename);
UNREFERENCED_PARAMETER(CopyStyle);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return(FALSE);
}
#endif
BOOL
SetupQueueDefaultCopy(
IN HSPFILEQ QueueHandle,
IN HINF InfHandle,
IN PCTSTR SourceRootPath,
IN PCTSTR SourceFilename,
IN PCTSTR TargetFilename,
IN DWORD CopyStyle
)
/*++
Routine Description:
Add a single file to the copy queue, using the default source media
and destination as specified in an inf file.
Arguments:
QueueHandle - supplies a handle to a setup file queue, as returned
by SetupOpenFileQueue.
InfHandle - supplies a handle to an open inf file, that contains the
[SourceDisksFiles] and [SourceDisksNames] sections.
This handle must be for a win95-style inf.
SourceRootPath - supplies the root directory for the intended source.
This should be a sharepoint or a device root such as a:\ or g:\.
SourceFilename - supplies the filename of the source file. Filename part
only.
TargetFilename - supplies the filename of the target file. Filename part
only.
CopyStyle - supplies flags that control the behavior of the copy operation
for this file.
Return Value:
Boolean value indicating outcome. If FALSE, GetLastError() returns
extended error information.
--*/
{
BOOL b;
b = pSetupQueueSingleCopy(
QueueHandle,
InfHandle,
NULL,
NULL,
SourceRootPath,
SourceFilename,
TargetFilename,
CopyStyle
);
return(b);
}
PSOURCE_MEDIA_INFO
pSetupQueueSourceMedia(
IN OUT PSP_FILE_QUEUE Queue,
IN OUT PSP_FILE_QUEUE_NODE QueueNode,
IN LONG SourceRootStringId,
IN PCTSTR SourceDescription, OPTIONAL
IN PCTSTR SourceTagfile OPTIONAL
)
/*++
Routine Description:
Set up a file queue node's source media descriptor pointer, creating a new
source media descriptor if necessary.
Arguments:
Queue - supplies pointer to file queue with which the queue node
is associated.
QueueNode - supplies file queue node whose source media descriptor pointer
is to be set.
SourceRootStringId - supplies string id of root to source (something like a:\).
SourceDescription - if specified, supplies a description for the media.
SourceTagfile - if specified, supplies a tag file for the media.
Ignored if SourceDescription is not specified.
Return Value:
Pointer to source media info structure, or NULL if out of memory.
--*/
{
LONG DescriptionStringId;
LONG TagfileStringId;
PSOURCE_MEDIA_INFO Source,LastSource;
BOOL b1,b2;
TCHAR TempTagfileString[MAX_PATH];
TCHAR TempSrcDescString[LINE_LEN];
//
// If no description is specified, force the tagfile to none.
//
if(!SourceDescription) {
SourceTagfile = NULL;
}
if(SourceDescription) {
//
// Description specified. See if it's in the table. If not,
// no need to search the list of media descriptors because we know
// we can't find a match.
//
// (We must first copy this string to a writeable buffer, to speed up the
// case-insensitive lookup.
//
lstrcpyn(TempSrcDescString, SourceDescription, SIZECHARS(TempSrcDescString));
DescriptionStringId = StringTableLookUpString(Queue->StringTable,
TempSrcDescString,
STRTAB_CASE_INSENSITIVE | STRTAB_BUFFER_WRITEABLE
);
b1 = (DescriptionStringId != -1);
} else {
//
// No description specified, look for a source media with -1 as the
// description string id
//
DescriptionStringId = -1;
b1 = TRUE;
}
if(SourceTagfile) {
//
// Tagfile specified. See if it's in the table. If not,
// no need to search the list of media descriptors because we know
// we can't find a match.
//
// (Again, we must first copy the string to a writeable buffer.
//
lstrcpyn(TempTagfileString, SourceTagfile, SIZECHARS(TempTagfileString));
TagfileStringId = StringTableLookUpString(Queue->StringTable,
TempTagfileString,
STRTAB_CASE_INSENSITIVE | STRTAB_BUFFER_WRITEABLE
);
b2 = (TagfileStringId != -1);
} else {
//
// No tagfile specified, look for a source media with -1 as the
// tagfile string id
//
TagfileStringId = -1;
b2 = TRUE;
}
//
// If we think there's a possibility of finding an existing source that
// matches the caller's parameters, scan the source media list looking
// for a match.
//
if(b1 && b2) {
for(Source=Queue->SourceMediaList; Source; Source=Source->Next) {
if((Source->Description == DescriptionStringId)
&& (Source->Tagfile == TagfileStringId)
&& (Source->SourceRootPath == SourceRootStringId)) {
//
// Got a match. Point the queue node at this source and return.
//
QueueNode->SourceMediaInfo = Source;
return(Source);
}
}
}
//
// Need to add a new source media descriptor.
// Allocate the structure and fill it in.
//
Source = MyMalloc(sizeof(SOURCE_MEDIA_INFO));
if(!Source) {
return(NULL);
}
Source->Next = NULL;
Source->CopyQueue = NULL;
Source->CopyNodeCount = 0;
if(SourceDescription) {
//
// Since we already passed this in for a case-insensitive lookup with a writeable
// buffer, we can add it case-sensitively, because it's already lower-cased.
//
Source->Description = StringTableAddString(Queue->StringTable,
TempSrcDescString,
STRTAB_CASE_SENSITIVE | STRTAB_ALREADY_LOWERCASE
);
//
// We also must add the description in its original case, since this is a displayable string.
// (We're safe in casting away the CONST-ness of this string, since it won't be modified.)
//
Source->DescriptionDisplayName = StringTableAddString(Queue->StringTable,
(PTSTR)SourceDescription,
STRTAB_CASE_SENSITIVE
);
if((Source->Description == -1) || (Source->DescriptionDisplayName == -1)) {
MyFree(Source);
return(NULL);
}
} else {
Source->Description = Source->DescriptionDisplayName = -1;
}
if(SourceTagfile) {
//
// Again, we already lower-cased this in a writeable buffer above.
//
Source->Tagfile = StringTableAddString(Queue->StringTable,
TempTagfileString,
STRTAB_CASE_SENSITIVE | STRTAB_ALREADY_LOWERCASE
);
if(Source->Tagfile == -1) {
MyFree(Source);
return(NULL);
}
} else {
Source->Tagfile = -1;
}
Source->SourceRootPath = SourceRootStringId;
if(Queue->SourceMediaList) {
for(LastSource=Queue->SourceMediaList; LastSource->Next; LastSource=LastSource->Next) ;
LastSource->Next = Source;
} else {
Queue->SourceMediaList = Source;
}
Queue->SourceMediaCount++;
QueueNode->SourceMediaInfo = Source;
return(Source);
}
BOOL
pSetupGetSourceAllInfo(
IN HINF InfHandle,
IN UINT SourceId,
OUT PCTSTR *Description,
OUT PCTSTR *Tagfile,
OUT PCTSTR *RelativePath
)
{
BOOL b;
DWORD RequiredSize;
PTSTR p;
DWORD ec;
//
// Get path relative to the source.
//
b = SetupGetSourceInfo(InfHandle,SourceId,SRCINFO_PATH,NULL,0,&RequiredSize);
if(!b) {
ec = GetLastError();
goto clean0;
}
p = MyMalloc(RequiredSize*sizeof(TCHAR));
if(!p) {
ec = ERROR_NOT_ENOUGH_MEMORY;
goto clean0;
}
SetupGetSourceInfo(InfHandle,SourceId,SRCINFO_PATH,p,RequiredSize,NULL);
*RelativePath = p;
//
// Get description.
//
b = SetupGetSourceInfo(InfHandle,SourceId,SRCINFO_DESCRIPTION,NULL,0,&RequiredSize);
if(!b) {
ec = GetLastError();
goto clean1;
}
p = MyMalloc(RequiredSize*sizeof(TCHAR));
if(!p) {
ec = ERROR_NOT_ENOUGH_MEMORY;
goto clean1;
}
SetupGetSourceInfo(InfHandle,SourceId,SRCINFO_DESCRIPTION,p,RequiredSize,NULL);
*Description = p;
//
// Get tagfile, if any.
//
b = SetupGetSourceInfo(InfHandle,SourceId,SRCINFO_TAGFILE,NULL,0,&RequiredSize);
if(!b) {
ec = GetLastError();
goto clean2;
}
p = MyMalloc(RequiredSize*sizeof(TCHAR));
if(!p) {
ec = ERROR_NOT_ENOUGH_MEMORY;
goto clean2;
}
SetupGetSourceInfo(InfHandle,SourceId,SRCINFO_TAGFILE,p,RequiredSize,NULL);
if(*p) {
*Tagfile = p;
} else {
MyFree(p);
*Tagfile = NULL;
}
return(TRUE);
clean2:
MyFree(*Description);
clean1:
MyFree(*RelativePath);
clean0:
SetLastError(ec);
return(FALSE);
}