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.
 
 
 
 
 
 

322 lines
6.9 KiB

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
cabinet.cpp
Abstract:
cabinet management Function calls for msm generation
Author:
Xiaoyu Wu(xiaoyuw) 01-Aug-2001
--*/
#include "msmgen.h"
#include "util.h"
extern BOOL __stdcall SxspDeleteDirectory(const CBaseStringBuffer &rdir);
#include <fci.h>
#include <fdi.h>
#include "msmfci.h"
#include "msmfdi.h"
ERF erf;
//
// FCI
//
HRESULT InitializeCabinetForWrite()
{
HFCI hfci;
CCAB cab_parameters;
client_state cs;
HRESULT hr = S_OK;
// Initialise our internal state
cs.total_compressed_size = 0;
cs.total_uncompressed_size = 0;
set_cab_parameters(&cab_parameters);
hfci = FCICreate(
&erf,
file_placed,
fci_mem_alloc,
fci_mem_free,
fci_open,
fci_read,
fci_write,
fci_close,
fci_seek,
fci_delete,
get_temp_file,
&cab_parameters,
&cs
);
if (hfci == NULL)
{
printf("CAB: FCICreate() failed: code %d [%s]\n",
erf.erfOper, return_fci_error_string(erf.erfOper));
SETFAIL_AND_EXIT;
}else
{
g_MsmInfo.m_hfci = hfci;
hfci= NULL;
}
Exit:
return hr;
}
HRESULT AddFileToCabinetW(PCWSTR full_filename, SIZE_T CchFullFileName, PCWSTR relative_filename, SIZE_T CchRelativePath)
{
HRESULT hr = S_OK;
CHAR pszpath[MAX_PATH];
CHAR pszfilename[MAX_PATH];
WideCharToMultiByte(
CP_ACP, 0, full_filename, (int)CchFullFileName,
pszpath, MAX_PATH, NULL, NULL);
pszpath[CchFullFileName] = '\0';
WideCharToMultiByte(
CP_ACP, 0, relative_filename, (int)CchRelativePath,
pszfilename, MAX_PATH, NULL, NULL);
pszfilename[CchRelativePath] = '\0';
if (FALSE == FCIAddFile(
g_MsmInfo.m_hfci,
pszpath, /* filename to add : fully qualified filename */
pszfilename, /* file name in cabinet file : relative filepath */
FALSE, /* file is not executable */
get_next_cabinet,
progress,
get_open_info,
COMPRESSION_TYPE))
{
fprintf(stderr, "adding file %s to the cabinet failed\n", pszpath);
SETFAIL_AND_EXIT;
}
Exit:
return hr;
}
HRESULT AddFileToCabinetA(PCSTR full_filename, SIZE_T CchFullFileName, PCSTR relative_filename, SIZE_T CchRelativePath)
{
HRESULT hr = S_OK;
WCHAR szFullFilename[MAX_PATH];
WCHAR szRelativeFilename[MAX_PATH];
swprintf(szFullFilename, L"%S", full_filename);
swprintf(szRelativeFilename, L"%S", relative_filename);
IFFAILED_EXIT(AddFileToCabinetW(szFullFilename, CchFullFileName, szRelativeFilename, CchRelativePath));
Exit:
return hr;
}
HRESULT CloseCabinet()
{
HRESULT hr = S_OK;
CurrentAssemblyReset;
if (FALSE == FCIFlushCabinet(
g_MsmInfo.m_hfci,
FALSE,
get_next_cabinet,
progress))
{
fprintf(stderr, "Flush Cabinet failed\n");
hr = HRESULT_FROM_WIN32(::GetLastError());
goto Exit;
}
if (FCIDestroy(g_MsmInfo.m_hfci) != TRUE)
{
SETFAIL_AND_EXIT;
}
else
g_MsmInfo.m_hfci = NULL;
Exit:
return hr;
}
//
// FDI
//
HRESULT MoveFilesInCabinetA(char * sourceCabinet)
{
HRESULT hr = S_OK;
HFDI hfdi = NULL;
ERF erf;
FDICABINETINFO fdici;
INT_PTR hf = -1;
DWORD num;
extern char dest_dir[MAX_PATH];
hfdi = FDICreate(
fdi_mem_alloc,
fdi_mem_free,
fdi_file_open,
fdi_file_read,
fdi_file_write,
fdi_file_close,
fdi_file_seek,
cpu80386,
&erf
);
if (hfdi == NULL)
{
printf("FDICreate() failed: code %d [%s]\n",
erf.erfOper, return_fdi_error_string(erf.erfOper)
);
SETFAIL_AND_EXIT;
}
hf = fdi_file_open(
sourceCabinet,
_O_BINARY | _O_RDONLY | _O_SEQUENTIAL,
0
);
if (hf == -1)
{
printf("Unable to open '%s' for input\n", sourceCabinet);
SETFAIL_AND_EXIT;
}
if (FALSE == FDIIsCabinet(
hfdi,
hf,
&fdici))
{
/*
* It is not a cabinet!, BUT it must be since it is named as MergeModule.cab in a msm
*/
printf(
"FDIIsCabinet() failed: '%s' is not a cabinet\n",
sourceCabinet
);
SETFAIL_AND_EXIT;
}
else
{
_close((int)hf);
#ifdef MSMGEN_TEST
printf(
"Information on cabinet file '%s'\n"
" Total length of cabinet file : %d\n"
" Number of folders in cabinet : %d\n"
" Number of files in cabinet : %d\n"
" Cabinet set ID : %d\n"
" Cabinet number in set : %d\n"
" RESERVE area in cabinet? : %s\n"
" Chained to prev cabinet? : %s\n"
" Chained to next cabinet? : %s\n"
"\n",
sourceCabinet,
fdici.cbCabinet,
fdici.cFolders,
fdici.cFiles,
fdici.setID,
fdici.iCabinet,
fdici.fReserve == TRUE ? "yes" : "no",
fdici.hasprev == TRUE ? "yes" : "no",
fdici.hasnext == TRUE ? "yes" : "no"
);
#endif
if ((fdici.fReserve == TRUE)|| (fdici.hasprev == TRUE) || (fdici.hasnext == TRUE))
{
printf("ERROR file format : MSI 1.5 support one and only one cabinet in MergeModule.cab!\n");
SETFAIL_AND_EXIT;
}
}
//
// create a temporary directory for use
//
num = ExpandEnvironmentStringsA(MSM_TEMP_CABIN_DIRECTORY_A, dest_dir, NUMBER_OF(dest_dir));
if ( (num == 0) || (num > NUMBER_OF(dest_dir)))
SETFAIL_AND_EXIT;
DWORD dwAttribs = GetFileAttributesA(dest_dir);
if (dwAttribs != (DWORD)(-1))
{
if ((dwAttribs & FILE_ATTRIBUTE_DIRECTORY) == 0 )
SETFAIL_AND_EXIT;
CStringBuffer sb;
WCHAR wdir[MAX_PATH];
num = ExpandEnvironmentStringsW(MSM_TEMP_CABIN_DIRECTORY_W, wdir, NUMBER_OF(wdir));
if ( (num == 0) || (num > NUMBER_OF(wdir)))
SETFAIL_AND_EXIT;
IFFALSE_EXIT(sb.Win32Assign(wdir, wcslen(wdir)));
IFFALSE_EXIT(SxspDeleteDirectory(sb));
}
IFFALSE_EXIT(CreateDirectoryA(dest_dir, NULL));
char * p = NULL;
char sourceDir[MAX_PATH];
p = strrchr(sourceCabinet, '\\');
ASSERT_NTC(p != NULL);
p ++; // skip "\"
strncpy(sourceDir, sourceCabinet, p - sourceCabinet);
sourceDir[p - sourceCabinet] = '\0';
if (TRUE != FDICopy(
hfdi,
p,
sourceDir,
0,
fdi_notification_function,
NULL,
NULL))
{
printf(
"FDICopy() failed: code %d [%s]\n",
erf.erfOper, return_fdi_error_string(erf.erfOper)
);
(void) FDIDestroy(hfdi);
return FALSE;
}
if (FDIDestroy(hfdi) != TRUE)
{
printf(
"FDIDestroy() failed: code %d [%s]\n",
erf.erfOper, return_fdi_error_string(erf.erfOper)
);
return FALSE;
}
hfdi = NULL;
Exit:
if (hfdi != NULL)
(void) FDIDestroy(hfdi);
if ( hf != -1)
_close((int)hf);
return hr;
}