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.
 
 
 
 
 
 

1006 lines
34 KiB

/*++
Copyright (C) 2000-2001 Microsoft Corporation
Module Name:
RepositoryPackager.CPP
Abstract:
Recursively packages the contents of the repository directory into a single file,
and unpackages it.
History:
paulall 07-26-00 Created.
a-shawnb 07-27-00 Finished.
--*/
#include "precomp.h"
#include <wbemcli.h>
#include "RepositoryPackager.h"
#include <arrtempl.h> // for CReleaseMe
#include <algorithm>
#include <functional>
#include <cstring>
#include "a51tools.h"
//#include <autoptr.h>
wchar_t * CRepositoryPackager::backupFiles_[] = {L"$WinMgmt.CFG",L"INDEX.BTR",L"OBJECTS.DATA",L"Mapping1.map",L"Mapping2.map", L"Mapping.Ver"};
wchar_t * CRepositoryPackager::repDirectory_ = L"FS";
int __cdecl _adap_wbem_wcsicmp(const unsigned short * a,const unsigned short * b)
{
return wbem_wcsicmp(a,b);
}
bool CRepositoryPackager::needBackup(const wchar_t * fileName) const
{
const int maxSize = sizeof(backupFiles_)/sizeof(backupFiles_[0]);
return (std::find_if(&backupFiles_[0], &backupFiles_[maxSize], std::not1(std::bind1st(std::ptr_fun(_adap_wbem_wcsicmp),fileName))) != backupFiles_+maxSize);
};
/******************************************************************************
*
* CRepositoryPackager::PackageRepository
*
* Description:
* Iterates deeply through the repository directly and packages it up
* into the given file specified by the given parameter.
* Repository directory is the one retrieved from the registry.
*
* Parameters:
* wszFilename: Filename we package everything up into
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::PackageRepository(const wchar_t *wszFilename)
{
HRESULT hres = WBEM_S_NO_ERROR;
CFileName wszRepositoryDirectory;
HANDLE hFile = INVALID_HANDLE_VALUE;
int lBackupFileNameLen = 0;
bool bBackupFileExists = false;
CFileName wszBackupFileName;
if ((wszBackupFileName == NULL) || (wszRepositoryDirectory == NULL))
hres = WBEM_E_OUT_OF_MEMORY;
//Get the root directory of the repository
if (SUCCEEDED(hres))
hres = GetRepositoryDirectory(wszRepositoryDirectory);
//Create a new file to package contents up to...
if (SUCCEEDED(hres))
{
hFile = CreateFileW(wszFilename, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
if ((GetLastError() != ERROR_FILE_EXISTS) && (GetLastError() != ERROR_ALREADY_EXISTS ))
{
hres = WBEM_E_INVALID_PARAMETER;
}
else
{
//We need to back up the existing file in case we fail and need to restore it
StringCchCopyW(wszBackupFileName, wszBackupFileName.Length(), wszFilename);
StringCchCatW(wszBackupFileName, wszBackupFileName.Length(), L".");
lBackupFileNameLen = wcslen(wszBackupFileName);
for (int i = 0; i != 100; i++)
{
_itow(i, wszBackupFileName+lBackupFileNameLen, 10);
if (MoveFileW(wszFilename, wszBackupFileName))
{
//We
Succeeded!
bBackupFileExists = true;
//Now we need to open the file again!
hFile = CreateFileW(wszFilename, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
hres = WBEM_E_INVALID_PARAMETER;
}
break;
}
}
//If we failed with all them we may as well just give up here!
if (!bBackupFileExists)
hres = WBEM_E_INVALID_PARAMETER;
}
}
}
//Write the package header...
if (SUCCEEDED(hres))
{
hres = PackageHeader(hFile);
}
if (SUCCEEDED(hres))
{
hres = PackageAllFiles(hFile, wszRepositoryDirectory);
}
//Write the end of package marker
if (SUCCEEDED(hres))
hres = PackageTrailer(hFile);
if (hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
//If things failed we should delete the file...
if (FAILED(hres))
DeleteFileW(wszFilename);
//If there is a backup file, rename it back in failure case
//or delete in other cases
if (FAILED(hres) && bBackupFileExists && wszBackupFileName)
MoveFileW(wszBackupFileName, wszFilename);
else if (bBackupFileExists && wszBackupFileName)
DeleteFileW(wszBackupFileName);
return hres;
}
/******************************************************************************
*
* CRepositoryPackager::UnpackageRepository
*
* Description:
* Given the filename of a packaged up repository we unpack everything
* into the repository directory specified in the registry. The
* directory should have no files in it before doing this.
*
* Parameters:
* wszFilename: Filename we unpackage everything from
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::UnpackageRepository(const wchar_t *wszFilename)
{
HRESULT hres = WBEM_S_NO_ERROR;
wchar_t wszRepositoryDirectory[MAX_PATH+1];
HANDLE hFile = INVALID_HANDLE_VALUE;
//Get the root directory of the repository
hres = GetRepositoryDirectory(wszRepositoryDirectory);
//open the file for unpacking...
if (SUCCEEDED(hres))
{
hFile = CreateFileW(wszFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
hres = WBEM_E_INVALID_PARAMETER;
}
//unpack the package header...
if (SUCCEEDED(hres))
{
hres = UnPackageHeader(hFile);
}
//unpack the file...
if (SUCCEEDED(hres))
{
hres = UnPackageContentsOfDirectory(hFile, wszRepositoryDirectory);
}
if (hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
//If things failed we should delete the partially unpacked repository...
if (FAILED(hres))
DeleteRepository();
return hres;
}
/******************************************************************************
*
* CRepositoryPackager::DeleteRepository
*
* Description:
* Delete all files and directories under the repository directory.
* The repository directory location is retrieved from the registry.
*
* Parameters:
* <none>
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::DeleteRepository()
{
HRESULT hr = WBEM_S_NO_ERROR;
wchar_t *wszRepositoryOrg = new wchar_t[MAX_PATH+1];
CVectorDeleteMe<wchar_t> vdm1(wszRepositoryOrg);
if (!wszRepositoryOrg)
hr = WBEM_E_OUT_OF_MEMORY;
if (SUCCEEDED(hr))
hr = GetRepositoryDirectory(wszRepositoryOrg);
//MOVE EACH OF THE FILES, ONE BY ONE
for (int i = 0; SUCCEEDED(hr) && (i != 6); i++)
{
static wchar_t *filename[] = {L"$WinMgmt.CFG",L"INDEX.BTR",L"OBJECTS.DATA",L"Mapping1.map",L"Mapping2.map", L"Mapping.Ver"};
CFileName wszDestinationFile;
if (!wszDestinationFile)
hr = WBEM_E_OUT_OF_MEMORY;
else
{
StringCchCopyW(wszDestinationFile, wszDestinationFile.Length(), wszRepositoryOrg);
if (i != 0)
{
StringCchCatW(wszDestinationFile, wszDestinationFile.Length(), L"\\fs");
}
StringCchCatW(wszDestinationFile, wszDestinationFile.Length(), filename[i]);
if (!DeleteFileW(wszDestinationFile))
{
if ((GetLastError() != ERROR_FILE_NOT_FOUND) && (GetLastError() != ERROR_PATH_NOT_FOUND))
{
hr = WBEM_E_FAILED;
break;
}
}
}
}
return hr;
}
HRESULT CRepositoryPackager::PackageAllFiles(HANDLE hFile, const wchar_t *wszRepositoryDirectory)
{
//
// internally PackageFile check for existence
// this is a matter only when $WinMgMt.CFG is packeged, since it cannot be there
// if PackeageFile is called from within the FindFirst/FindNext loop, then the
// existence of the file is ensured by the context
//
HRESULT hres = PackageFile(hFile, wszRepositoryDirectory, backupFiles_[0]);
if (FAILED(hres))
return hres;
hres = PackageDirectory(hFile, wszRepositoryDirectory, repDirectory_);
return hres;
}
/******************************************************************************
*
* CRepositoryPackager::PackageContentsOfDirectory
*
* Description:
* Given a directory, iterates through all files and directories and
* calls into the function to package it into the file specified by the
* file handle passed to the method.
*
* Parameters:
* hFile: Handle to the destination file.
* wszRepositoryDirectory: Directory to process
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::PackageContentsOfDirectory(HANDLE hFile, const wchar_t *wszRepositoryDirectory)
{
HRESULT hres = WBEM_S_NO_ERROR;
WIN32_FIND_DATAW findFileData;
HANDLE hff = INVALID_HANDLE_VALUE;
//create file search pattern...
CFileName wszSearchPattern;
if (wszSearchPattern == NULL)
hres = WBEM_E_OUT_OF_MEMORY;
else
{
StringCchCopyW(wszSearchPattern, wszSearchPattern.Length(), wszRepositoryDirectory);
StringCchCatW(wszSearchPattern, wszSearchPattern.Length(), L"\\*");
}
//Start the file iteration in this directory...
if (SUCCEEDED(hres))
{
hff = FindFirstFileW(wszSearchPattern, &findFileData);
if (hff == INVALID_HANDLE_VALUE)
{
hres = WBEM_E_FAILED;
}
}
if (SUCCEEDED(hres))
{
do
{
//If we have a filename of '.' or '..' we ignore it...
if ((wcscmp(findFileData.cFileName, L".") == 0) ||
(wcscmp(findFileData.cFileName, L"..") == 0))
{
//Do nothing with these...
}
else
{
//This is a file, so we need to deal with that...
hres = PackageFile(hFile, wszRepositoryDirectory, findFileData.cFileName);
if (FAILED(hres))
break;
}
} while (FindNextFileW(hff, &findFileData));
}
if (hff != INVALID_HANDLE_VALUE)
FindClose(hff);
return hres;
}
/******************************************************************************
*
* CRepositoryPackager::GetRepositoryDirectory
*
* Description:
* Retrieves the location of the repository directory from the registry.
*
* Parameters:
* wszRepositoryDirectory: Array to store location in.
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::GetRepositoryDirectory(wchar_t wszRepositoryDirectory[MAX_PATH+1])
{
HKEY hKey;
long lRes = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\WBEM\\CIMOM",
0, KEY_READ, &hKey);
if(lRes)
return WBEM_E_FAILED;
wchar_t wszTmp[MAX_PATH + 1];
DWORD dwLen = (MAX_PATH + 1)*sizeof(wchar_t);
lRes = RegQueryValueExW(hKey, L"Repository Directory", NULL, NULL,
(LPBYTE)wszTmp, &dwLen);
RegCloseKey(hKey);
if(lRes)
return WBEM_E_FAILED;
if (ExpandEnvironmentStringsW(wszTmp,wszRepositoryDirectory, MAX_PATH + 1) == 0)
return WBEM_E_FAILED;
return WBEM_S_NO_ERROR;
}
/******************************************************************************
*
* CRepositoryPackager::PackageHeader
*
* Description:
* Stores the header package in the given file. This is a footprint
* so we can recognise if this really is one of our files when
* we try to decode it. Also it allows us to version it.
*
* Parameters:
* hFile: File handle to store header in.
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::PackageHeader(HANDLE hFile)
{
HRESULT hres = WBEM_S_NO_ERROR;
PACKAGE_HEADER header;
StringCchCopyA(header.szSignature, 10, "FS PKG1.1"); //NOTE! MAXIMUM OF 10 CHARACTERS (INCLUDING TERMINATOR!)
DWORD dwSize = 0;
if ((WriteFile(hFile, &header, sizeof(header), &dwSize, NULL) == 0) || (dwSize != sizeof(header)))
hres = WBEM_E_FAILED;
return hres;
}
/******************************************************************************
*
* CRepositoryPackager::PackageDirectory
*
* Description:
* This is the code which processes a directory. It stores the namespace
* header and footer marker in the file, and also iterates through
* all files and directories in that directory.
*
* Parameters:
* hFile: File handle to store directory information in.
* wszParentDirectory: Full path of parent directory
* eszSubDirectory: Name of sub-directory to process
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::PackageDirectory(HANDLE hFile, const wchar_t *wszParentDirectory, wchar_t *wszSubDirectory)
{
HRESULT hres = WBEM_S_NO_ERROR;
{
PACKAGE_SPACER_NAMESPACE header;
header.dwSpacerType = PACKAGE_TYPE_NAMESPACE_START;
StringCchCopyW(header.wszNamespaceName, MAX_PATH+1, wszSubDirectory);
DWORD dwSize = 0;
if ((WriteFile(hFile, &header, sizeof(header), &dwSize, NULL) == 0) || (dwSize != sizeof(header)))
hres = WBEM_E_FAILED;
}
//Get full path of new directory...
CFileName wszFullDirectoryName;
if (wszFullDirectoryName == NULL) hres = WBEM_E_OUT_OF_MEMORY;
if (SUCCEEDED(hres))
{
StringCchCopyW(wszFullDirectoryName, wszFullDirectoryName.Length(), wszParentDirectory);
StringCchCatW(wszFullDirectoryName, wszFullDirectoryName.Length(), L"\\");
StringCchCatW(wszFullDirectoryName, wszFullDirectoryName.Length(), wszSubDirectory);
}
//Package the contents of that directory...
if (SUCCEEDED(hres))
{
hres = PackageContentsOfDirectory(hFile, wszFullDirectoryName);
}
//Now need to write the end of package marker...
if (SUCCEEDED(hres))
{
PACKAGE_SPACER header2;
header2.dwSpacerType = PACKAGE_TYPE_NAMESPACE_END;
DWORD dwSize = 0;
if ((WriteFile(hFile, &header2, sizeof(header2), &dwSize, NULL) == 0) || (dwSize != sizeof(header2)))
hres = WBEM_E_FAILED;
}
return hres;
}
/******************************************************************************
*
* CRepositoryPackager::PackageFile
*
* Description:
* This is the code which processes a file. It stores the file header
* and the contents of the file into the destination file whose handle
* is passed in. The file directory and name is passed in.
*
* Parameters:
* hFile: File handle to store directory information in.
* wszParentDirectory: Full path of parent directory
* wszFilename: Name of file to process
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::PackageFile(HANDLE hFile, const wchar_t *wszParentDirectory, wchar_t *wszFilename)
{
if (needBackup(wszFilename) == false) return WBEM_S_NO_ERROR;
HRESULT hres = WBEM_S_NO_ERROR;
PACKAGE_SPACER_FILE header;
header.dwSpacerType = PACKAGE_TYPE_FILE;
StringCchCopyW(header.wszFileName, MAX_PATH+1, wszFilename);
WIN32_FILE_ATTRIBUTE_DATA fileAttribs;
CFileName wszFullFileName;
if (wszFullFileName == NULL)
hres = WBEM_E_OUT_OF_MEMORY;
if (SUCCEEDED(hres))
{
StringCchCopyW(wszFullFileName, wszFullFileName.Length(), wszParentDirectory);
StringCchCatW(wszFullFileName, wszFullFileName.Length(), L"\\");
StringCchCatW(wszFullFileName, wszFullFileName.Length(), wszFilename);
if (GetFileAttributesExW(wszFullFileName, GetFileExInfoStandard, &fileAttribs) == 0)
{
if (ERROR_FILE_NOT_FOUND == GetLastError())
return WBEM_S_NO_ERROR;
else
hres = WBEM_E_FAILED;
}
else
{
header.dwFileSize = fileAttribs.nFileSizeLow;
}
}
//Write header...
if (SUCCEEDED(hres))
{
DWORD dwSize = 0;
if ((WriteFile(hFile, &header, sizeof(header), &dwSize, NULL) == 0) || (dwSize != sizeof(header)))
hres = WBEM_E_FAILED;
}
//Now need to write actual contents of file to current one... but only if the file is not 0 bytes long...
if (SUCCEEDED(hres) && (header.dwFileSize != 0))
{
HANDLE hFromFile = CreateFileW(wszFullFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFromFile == INVALID_HANDLE_VALUE)
hres = WBEM_E_FAILED;
BYTE *pFileBlob = NULL;
if (SUCCEEDED(hres))
{
pFileBlob = new BYTE[header.dwFileSize];
if (pFileBlob == NULL)
hres = WBEM_E_OUT_OF_MEMORY;
}
if (SUCCEEDED(hres))
{
DWORD dwSize = 0;
if ((ReadFile(hFromFile, pFileBlob, header.dwFileSize, &dwSize, NULL) == 0) || (dwSize != header.dwFileSize))
hres = WBEM_E_FAILED;
}
if (SUCCEEDED(hres))
{
DWORD dwSize = 0;
if ((WriteFile(hFile, pFileBlob, header.dwFileSize, &dwSize, NULL) == 0) || (dwSize != header.dwFileSize))
hres = WBEM_E_FAILED;
}
delete pFileBlob;
if (hFromFile != INVALID_HANDLE_VALUE)
CloseHandle(hFromFile);
}
return hres;
}
/******************************************************************************
*
* CRepositoryPackager::PackageTrailer
*
* Description:
* Writes the end of file marker to the file.
*
* Parameters:
* hFile: File handle to store directory information in.
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::PackageTrailer(HANDLE hFile)
{
HRESULT hres = WBEM_S_NO_ERROR;
PACKAGE_SPACER trailer;
trailer.dwSpacerType = PACKAGE_TYPE_END_OF_FILE;
DWORD dwSize = 0;
if ((WriteFile(hFile, &trailer, sizeof(trailer), &dwSize, NULL) == 0) || (dwSize != sizeof(trailer)))
hres = WBEM_E_FAILED;
return hres;
}
/******************************************************************************
*
* CRepositoryPackager::UnPackageHeader
*
* Description:
* Unpacks the header package in the given file. This allows us to recognise
* if this really is one of our files. Also it allows us to version it.
*
* Parameters:
* hFile: File handle to unpack header from.
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::UnPackageHeader(HANDLE hFile)
{
HRESULT hres = WBEM_S_NO_ERROR;
PACKAGE_HEADER header;
DWORD dwSize = 0;
if ((ReadFile(hFile, &header, sizeof(header), &dwSize, NULL) == 0) || (dwSize != sizeof(header)))
{
hres = WBEM_E_FAILED;
}
else if (strncmp(header.szSignature,"FS PKG1.1", 9) != 0)
{
hres = WBEM_E_FAILED;
}
return hres;
}
/******************************************************************************
*
* CRepositoryPackager::UnPackageContentsOfDirectory
*
* Description:
* Unpack the contents of a namespace/directory.
* If a subdirectory is encountered, then it calls UnPackageDirectory to handle it.
* If a file is encountered, then it calls UnPackageFile to handle it.
* If no errors occur, then it will enventually encounter the end of the namespace,
* which will terminate the loop and return control to the calling function.
*
* Parameters:
* hFile: Handle to the file to unpack from
* wszRepositoryDirectory: Directory to write to.
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::UnPackageContentsOfDirectory(HANDLE hFile, const wchar_t *wszRepositoryDirectory)
{
HRESULT hres = WBEM_S_NO_ERROR;
PACKAGE_SPACER header;
DWORD dwSize;
while (hres == WBEM_S_NO_ERROR)
{
// this loop will be exited when we either
// - successfully process a complete directory/namespace
// - encounter an error
dwSize = 0;
if ((ReadFile(hFile, &header, sizeof(header), &dwSize, NULL) == 0) || (dwSize != sizeof(header)))
{
hres = WBEM_E_FAILED;
}
else if (header.dwSpacerType == PACKAGE_TYPE_NAMESPACE_START)
{
hres = UnPackageDirectory(hFile, wszRepositoryDirectory);
}
else if (header.dwSpacerType == PACKAGE_TYPE_NAMESPACE_END)
{
// done with this directory
break;
}
else if (header.dwSpacerType == PACKAGE_TYPE_FILE)
{
hres = UnPackageFile(hFile, wszRepositoryDirectory);
}
else if (header.dwSpacerType == PACKAGE_TYPE_END_OF_FILE)
{
// done unpacking
break;
}
else
{
hres = WBEM_E_FAILED;
}
}
return hres;
}
/******************************************************************************
*
* CRepositoryPackager::UnPackageDirectory
*
* Description:
* Unpack the start of a namespace, then call UnPackageContentsOfDirectory
* to handle everything within it.
*
* Parameters:
* hFile: File handle to unpack directory information from.
* wszParentDirectory: Full path of parent directory
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::UnPackageDirectory(HANDLE hFile, const wchar_t *wszParentDirectory)
{
PACKAGE_SPACER_NAMESPACE header;
// read namespace/directory name
DWORD dwSize = 0;
DWORD dwSizeToRead = sizeof(header)-sizeof(PACKAGE_SPACER);
if ((ReadFile(hFile, ((LPBYTE)&header)+sizeof(PACKAGE_SPACER), dwSizeToRead, &dwSize, NULL) == 0) || (dwSize != dwSizeToRead))
{
return WBEM_E_FAILED;
}
//Get full path of new directory...
CFileName wszFullDirectoryName;
if (NULL == (wchar_t *)wszFullDirectoryName) return WBEM_E_OUT_OF_MEMORY;
StringCchCopyW(wszFullDirectoryName, wszFullDirectoryName.Length(), wszParentDirectory);
StringCchCatW(wszFullDirectoryName, wszFullDirectoryName.Length(), L"\\");
StringCchCatW(wszFullDirectoryName, wszFullDirectoryName.Length(), header.wszNamespaceName);
// create directory
if (!CreateDirectoryW(wszFullDirectoryName, NULL))
{
if (GetLastError() != ERROR_ALREADY_EXISTS) return WBEM_E_FAILED;
}
// UnPackage the contents into the new directory...
return UnPackageContentsOfDirectory(hFile, wszFullDirectoryName);
}
/******************************************************************************
*
* CRepositoryPackager::UnPackageFile
*
* Description:
* Unpack a file.
*
* Parameters:
* hFile: File handle to unpack file information from.
* wszParentDirectory: Full path of parent directory
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::UnPackageFile(HANDLE hFile, const wchar_t *wszParentDirectory)
{
HRESULT hres = WBEM_S_NO_ERROR;
PACKAGE_SPACER_FILE header;
// read file name and size
DWORD dwSize = 0;
DWORD dwSizeToRead = sizeof(header)-sizeof(PACKAGE_SPACER);
if ((ReadFile(hFile, ((LPBYTE)&header)+sizeof(PACKAGE_SPACER), dwSizeToRead, &dwSize, NULL) == 0) || (dwSize != dwSizeToRead))
{
hres = WBEM_E_FAILED;
}
//Get full path of new file...
CFileName wszFullFileName;
if (NULL == (wchar_t *)wszFullFileName) hres = WBEM_E_OUT_OF_MEMORY;
if (SUCCEEDED(hres))
{
StringCchCopyW(wszFullFileName, wszFullFileName.Length(), wszParentDirectory);
StringCchCatW(wszFullFileName, wszFullFileName.Length(), L"\\");
StringCchCatW(wszFullFileName, wszFullFileName.Length(), header.wszFileName);
}
// create the file
HANDLE hNewFile = INVALID_HANDLE_VALUE;
if (SUCCEEDED(hres))
{
hNewFile = CreateFileW(wszFullFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hNewFile == INVALID_HANDLE_VALUE)
hres = WBEM_E_FAILED;
}
// read file blob and write to file if size is greater than zero
if (SUCCEEDED(hres))
{
if (header.dwFileSize > 0)
{
BYTE* pFileBlob = new BYTE[header.dwFileSize];
if (pFileBlob == NULL)
hres = WBEM_E_OUT_OF_MEMORY;
if (SUCCEEDED(hres))
{
dwSize = 0;
if ((ReadFile(hFile, pFileBlob, header.dwFileSize, &dwSize, NULL) == 0) || (dwSize != header.dwFileSize))
{
hres = WBEM_E_FAILED;
}
}
// write file
if (SUCCEEDED(hres))
{
dwSize = 0;
if ((WriteFile(hNewFile, pFileBlob, header.dwFileSize, &dwSize, NULL) == 0) || (dwSize != header.dwFileSize))
hres = WBEM_E_FAILED;
}
if (pFileBlob)
delete pFileBlob;
}
}
if (hNewFile != INVALID_HANDLE_VALUE)
CloseHandle(hNewFile);
return hres;
}
/******************************************************************************
*
* CRepositoryPackager::DeleteContentsOfDirectory
*
* Description:
* Given a directory, iterates through all files and directories and
* calls into the function to delete it.
*
* Parameters:
* wszRepositoryDirectory: Directory to process
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::DeleteContentsOfDirectory(const wchar_t *wszRepositoryDirectory)
{
HRESULT hres = WBEM_S_NO_ERROR;
CFileName wszFullFileName;
if (wszFullFileName == NULL)
return WBEM_E_OUT_OF_MEMORY;
WIN32_FIND_DATAW findFileData;
HANDLE hff = INVALID_HANDLE_VALUE;
//create file search pattern...
CFileName wszSearchPattern;
if (wszSearchPattern == NULL)
hres = WBEM_E_OUT_OF_MEMORY;
else
{
StringCchCopyW(wszSearchPattern, wszSearchPattern.Length(), wszRepositoryDirectory);
StringCchCatW(wszSearchPattern, wszSearchPattern.Length(), L"\\*");
}
//Start the file iteration in this directory...
if (SUCCEEDED(hres))
{
hff = FindFirstFileW(wszSearchPattern, &findFileData);
if (hff == INVALID_HANDLE_VALUE)
{
hres = WBEM_E_FAILED;
}
}
if (SUCCEEDED(hres))
{
do
{
//If we have a filename of '.' or '..' we ignore it...
if ((wcscmp(findFileData.cFileName, L".") == 0) ||
(wcscmp(findFileData.cFileName, L"..") == 0))
{
//Do nothing with these...
}
else if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
//This is a directory, so we need to deal with that...
hres = PackageDeleteDirectory(wszRepositoryDirectory, findFileData.cFileName);
if (FAILED(hres))
break;
}
else
{
//This is a file, so we need to deal with that...
StringCchCopyW(wszFullFileName, wszFullFileName.Length(), wszRepositoryDirectory);
StringCchCatW(wszFullFileName, wszFullFileName.Length(), L"\\");
StringCchCatW(wszFullFileName, wszFullFileName.Length(), findFileData.cFileName);
if (!DeleteFileW(wszFullFileName))
{
hres = WBEM_E_FAILED;
break;
}
}
} while (FindNextFileW(hff, &findFileData));
}
if (hff != INVALID_HANDLE_VALUE)
FindClose(hff);
return hres;
}
/******************************************************************************
*
* CRepositoryPackager::PackageDeleteDirectory
*
* Description:
* This is the code which processes a directory. It iterates through
* all files and directories in that directory.
*
* Parameters:
* wszParentDirectory: Full path of parent directory
* eszSubDirectory: Name of sub-directory to process
*
* Return:
* HRESULT: WBEM_S_NO_ERROR If successful
* WBEM_E_OUT_OF_MEMORY If out of memory
* WBEM_E_FAILED If anything else failed
*
******************************************************************************
*/
HRESULT CRepositoryPackager::PackageDeleteDirectory(const wchar_t *wszParentDirectory, wchar_t *wszSubDirectory)
{
HRESULT hres = WBEM_S_NO_ERROR;
//Get full path of new directory...
CFileName wszFullDirectoryName;
if (wszFullDirectoryName == NULL) return WBEM_E_OUT_OF_MEMORY;
if (SUCCEEDED(hres))
{
StringCchCopyW(wszFullDirectoryName, wszFullDirectoryName.Length(), wszParentDirectory);
StringCchCatW(wszFullDirectoryName, wszFullDirectoryName.Length(), L"\\");
StringCchCatW(wszFullDirectoryName, wszFullDirectoryName.Length(), wszSubDirectory);
}
//Package the contents of that directory...
if (SUCCEEDED(hres))
{
hres = DeleteContentsOfDirectory(wszFullDirectoryName);
}
// now that the directory is empty, remove it
if (!RemoveDirectoryW(wszFullDirectoryName))
hres = WBEM_E_FAILED;
return hres; }