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.
 
 
 
 
 
 

278 lines
6.3 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
optdirs.c
Abstract:
Routines for copying optional directories.
Author:
Ted Miller (tedm) 7-Jun-1995
Revision History:
--*/
#include "setupp.h"
#pragma hdrstop
PWSTR OptionalDirSpec;
PWSTR *OptionalDirs;
UINT OptionalDirCount;
BOOL
InitializeOptionalDirList(
VOID
)
/*++
Routine Description:
Initialize the list of optional directories by transforming a
*-delineated list of directories into an array of strings.
Arguments:
None.
Return Value:
Boolean value indicating whether initialization was successful.
If not an entry will have been logged indicating why.
--*/
{
PWSTR p,q;
WCHAR c;
UINT Count,i,Len;
//
// The number of directories is equal to the number of *'s plus one.
//
Len = lstrlen(OptionalDirSpec);
OptionalDirCount = 1;
for(Count=0; Count<Len; Count++) {
if(OptionalDirSpec[Count] == L'*') {
OptionalDirCount++;
}
}
OptionalDirs = MyMalloc(OptionalDirCount * sizeof(PWSTR));
if(!OptionalDirs) {
LogItem1(LogSevError,MSG_LOG_OPTIONAL_DIRS,MSG_LOG_OUTOFMEMORY);
return(FALSE);
}
ZeroMemory(OptionalDirs,OptionalDirCount * sizeof(PWSTR));
p = OptionalDirSpec;
Count = 0;
do {
if((q = wcschr(p,L'*')) == NULL) {
q = wcschr(p,0);
}
c = *q;
*q = 0;
OptionalDirs[Count] = DuplicateString(p);
*q = c;
if(!OptionalDirs[Count]) {
LogItem1(LogSevError,MSG_LOG_OPTIONAL_DIRS,MSG_LOG_OUTOFMEMORY);
for(i=0; i<Count; i++) {
MyFree(OptionalDirs[i]);
}
MyFree(OptionalDirs);
return(FALSE);
}
Count++;
p = q+1;
} while(c);
return(TRUE);
}
BOOL
QueueFilesInOptionalDirectory(
IN HSPFILEQ FileQ,
IN PCWSTR Directory
)
{
WCHAR FileDirSpec[MAX_PATH];
WIN32_FIND_DATA FindData;
HANDLE FindHandle;
WCHAR c1,c2,c3;
BOOL b;
//
// Create the directory in the user's nt tree.
//
GetWindowsDirectory(FileDirSpec,MAX_PATH);
ConcatenatePaths(FileDirSpec,Directory,MAX_PATH,NULL);
CreateDirectory(FileDirSpec,NULL);
//
// Form the full name of the directory to iterate
// and add on the search spec.
//
lstrcpyn(FileDirSpec,SourcePath,MAX_PATH);
ConcatenatePaths(FileDirSpec,Directory,MAX_PATH,NULL);
ConcatenatePaths(FileDirSpec,L"*",MAX_PATH,NULL);
b = TRUE;
FindHandle = FindFirstFile(FileDirSpec,&FindData);
if(FindHandle != INVALID_HANDLE_VALUE) {
do {
if(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
//
// It's a directory. Ignore if current or parent dir spec (. or ..).
//
c1 = FindData.cFileName[0];
c2 = FindData.cFileName[1];
c3 = FindData.cFileName[2];
if(!(((c1 == TEXT('.')) && !c2) || ((c1 == TEXT('.')) && (c2 == TEXT('.')) && !c3))) {
//
// Recurse to handle the child directory.
//
lstrcpyn(FileDirSpec,Directory,MAX_PATH);
ConcatenatePaths(FileDirSpec,FindData.cFileName,MAX_PATH,NULL);
b = QueueFilesInOptionalDirectory(FileQ,FileDirSpec);
}
} else {
//
// It's a file. Queue it up for copy.
//
GetWindowsDirectory(FileDirSpec,MAX_PATH);
ConcatenatePaths(FileDirSpec,Directory,MAX_PATH,NULL);
b = SetupQueueCopy(
FileQ,
SourcePath,
Directory,
FindData.cFileName,
NULL,
NULL,
FileDirSpec,
FindData.cFileName,
SP_COPY_DELETESOURCE
);
if(!b) {
LogItem2(
LogSevError,
MSG_LOG_OPTIONAL_DIR,
Directory,
MSG_LOG_X_RETURNED_WINERR,
L"SetupQueueCopy",
GetLastError()
);
}
}
} while(b && FindNextFile(FindHandle,&FindData));
FindClose(FindHandle);
}
return(b);
}
BOOL
CopyOptionalDirectories(
VOID
)
/*++
Routine Description:
Arguments:
None.
Return Value:
Boolean value indicating whether copying was successful.
If not an entry will have been logged indicating why.
--*/
{
UINT u;
BOOL b;
HSPFILEQ FileQ;
PVOID QueueCallbackInfo;
HWND Billboard;
if(!OptionalDirSpec) {
return(TRUE);
}
Billboard = DisplayBillboard(MainWindowHandle,MSG_PREPARING_OPTDIRS);
//
// Initialize the optional directory list.
//
if(!InitializeOptionalDirList()) {
KillBillboard(Billboard);
return(FALSE);
}
//
// Initialize a setup file queue.
//
FileQ = SetupOpenFileQueue();
if(FileQ == INVALID_HANDLE_VALUE) {
LogItem1(LogSevError,MSG_LOG_OPTIONAL_DIRS,MSG_LOG_OUTOFMEMORY);
KillBillboard(Billboard);
return(FALSE);
}
QueueCallbackInfo = SetupInitDefaultQueueCallback(MainWindowHandle);
if(!QueueCallbackInfo) {
SetupCloseFileQueue(FileQ);
LogItem1(LogSevError,MSG_LOG_OPTIONAL_DIRS,MSG_LOG_OUTOFMEMORY);
KillBillboard(Billboard);
return(FALSE);
}
//
// Queue the files in each directory.
//
b = TRUE;
for(u=0; u<OptionalDirCount; u++) {
if(!QueueFilesInOptionalDirectory(FileQ,OptionalDirs[u])) {
b = FALSE;
}
}
KillBillboard(Billboard);
//
// Copy the files in the queue. We do this even if some of the queue
// opeations failed, so we get at least a subset of the files copied over.
//
if(!SetupCommitFileQueue(MainWindowHandle,FileQ,SetupDefaultQueueCallback,QueueCallbackInfo)) {
LogItem0(LogSevWarning,MSG_LOG_OPTIONAL_DIR_COPY);
b = FALSE;
}
SetupTermDefaultQueueCallback(QueueCallbackInfo);
SetupCloseFileQueue(FileQ);
return(b);
}