|
|
#ifndef UTIL_H
#define UTIL_H
#pragma once
#include "fusionheap.h"
#include "wincrypt.h"
#include "fusionhandle.h"
#include "numberof.h"
#pragma warning(push)
#pragma warning(disable: 4201)
inline USHORT FusionGetMajorFromVersionHighHalf(DWORD dwVerHigh) { return HIWORD(dwVerHigh); }
inline USHORT FusionGetMinorFromVersionHighHalf(DWORD dwVerHigh) { return LOWORD(dwVerHigh); }
inline USHORT FusionGetRevisionFromVersionLowHalf(DWORD dwVerLow) { return HIWORD(dwVerLow); }
inline USHORT FusionGetBuildFromVersionLowHalf(DWORD dwVerLow) { return LOWORD(dwVerLow); }
#include "debmacro.h"
#include "FusionArray.h"
#include "fusionbuffer.h"
#include "EnumBitOperations.h"
//
// FusionCopyString() has a non-obvious interface due to the overloading of
// pcchBuffer to both describe the size of the buffer on entry and the number of
// characters required on exit.
//
// prgchBuffer is the buffer to write to. If *pcchBuffer is zero when FusionCopyString()
// is called, it may be NULL.
//
// pcchBuffer is a required parameter, which on entry must contain the number of unicode
// characters in the buffer pointed to by prgchBuffer. On exit, if the buffer was
// not large enough to hold the character string, including a trailing null,
// it is set to the number of WCHARs required to hold the string, including the
// trailing null, and HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) is returned.
//
// If the buffer is large enough, *pcchBuffer is set to the number of characters
// written into the buffer, including the trailing null character.
//
// This is contrary to most functions which return the number of characters written
// not including the trailing null, but since both on input and in the error case,
// it deals with the size of the buffer required rather than the number of non-
// null characters written, it seems inconsistent to only in the success case
// omit the null from the count.
//
// szIn is a pointer to sequence of unicode characters to be copied.
//
// cchIn is the number of Unicode characters in the character string to copy. If a
// value less than zero is passed in, szIn must point to a null-terminated string,
// and the current length of the string is used. If a value zero or greater is
// passed, exactly that many characters are assumed to be in the character string.
//
HRESULT FusionCopyString( WCHAR *prgchBuffer, SIZE_T *pcchBuffer, LPCWSTR szIn, SIZE_T cchIn );
BOOL FusionDupString( PWSTR *ppszOut, PCWSTR szIn, SIZE_T cchIn );
BOOL SxspMapLANGIDToCultures( LANGID langid, CBaseStringBuffer &rbuffGeneric, CBaseStringBuffer &rbuffSpecific );
BOOL SxspMapCultureToLANGID( PCWSTR pcwszCultureString, LANGID &lid, PBOOL pfFound );
typedef struct _SXSP_LANGUAGE_BUFFER_PAIR { CBaseStringBuffer * m_Generic; CBaseStringBuffer * m_Specific; } SXSP_LANGUAGE_BUFFER_PAIR, *PSXSP_LANGUAGE_BUFFER_PAIR; typedef const SXSP_LANGUAGE_BUFFER_PAIR * PCSXSP_LANGUAGE_BUFFER_PAIR;
BOOL SxspCultureStringToCultureStrings( PCWSTR pcwszCultureString, bool & rfFoundOut, SXSP_LANGUAGE_BUFFER_PAIR & LanguagePair );
BOOL FusionpParseProcessorArchitecture( IN PCWSTR String, IN SIZE_T Cch, OUT USHORT *ProcessorArchitecture OPTIONAL, bool &rfValid );
BOOL FusionpFormatProcessorArchitecture( IN USHORT ProcessorArchitecture, CBaseStringBuffer &rBuffer );
BOOL FusionpFormatEnglishLanguageName( IN LANGID LangID, CBaseStringBuffer &rBuffer );
/*-----------------------------------------------------------------------------
like ::CreateDirectoryW, but will create the parent directories as needed -----------------------------------------------------------------------------*/ BOOL FusionpCreateDirectories( PCWSTR pszDirectory, SIZE_T cchDirectory );
/*-----------------------------------------------------------------------------
'\\' or '/' -----------------------------------------------------------------------------*/ BOOL FusionpIsPathSeparator( WCHAR ch );
/*-----------------------------------------------------------------------------
just the 52 chars a-zA-Z, need to check with fs -----------------------------------------------------------------------------*/ BOOL FusionpIsDriveLetter( WCHAR ch );
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
VOID FusionpSetLastErrorFromHRESULT( HRESULT hr );
DWORD FusionpHRESULTToWin32( HRESULT hr );
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
class CFusionDirectoryDifference;
BOOL FusionpCompareDirectoriesSizewiseRecursively( CFusionDirectoryDifference* pResult, const CBaseStringBuffer &rdir1, const CBaseStringBuffer &rdir2 );
class CFusionDirectoryDifference { private: // deliberately unimplemented
CFusionDirectoryDifference(const CFusionDirectoryDifference&); VOID operator=(const CFusionDirectoryDifference&); public: CFusionDirectoryDifference() : m_e(eEqual), m_pstr1(&m_str1), m_pstr2(&m_str2) { }
VOID DbgPrint( PCWSTR dir1, PCWSTR dir2 );
public: enum E { eEqual, eExtraOrMissingFile, eMismatchedFileSize, eMismatchedFileCount, eFileDirectoryMismatch };
E m_e;
union { struct { CBaseStringBuffer * m_pstr1; CBaseStringBuffer * m_pstr2; }; struct // eExtraOrMissingFile
{ CBaseStringBuffer * m_pstrExtraOrMissingFile; }; struct // eMismatchFileSize
{ CBaseStringBuffer * m_pstrMismatchedSizeFile1; CBaseStringBuffer * m_pstrMismatchedSizeFile2; ULONGLONG m_nMismatchedFileSize1; ULONGLONG m_nMismatchedFileSize2; }; struct // eMismatchFileCount
{ CBaseStringBuffer * m_pstrMismatchedCountDir1; CBaseStringBuffer * m_pstrMismatchedCountDir2; ULONGLONG m_nMismatchedFileCount1; ULONGLONG m_nMismatchedFileCount2; }; struct // eFileDirectoryMismatch
{ CBaseStringBuffer * m_pstrFile; CBaseStringBuffer * m_pstrDirectory; }; };
// private:
CStringBuffer m_str1; CStringBuffer m_str2; };
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
class CFusionFilePathAndSize { public: CFusionFilePathAndSize() : m_size(0), m_bHasHashInfo(false), m_HashAlgorithm(0) { }
// bsearch and qsort accept optionally subtley different functions
// bsearch looks for a key in an array, the key and the array elements
// can be of different types, qsort compares only elements in the array
static int __cdecl QsortComparePath(const void*, const void*);
// for qsort/bsearch an array of pointers to CFusionFilePathAndSize
static int __cdecl QsortIndirectComparePath(const void*, const void*);
CStringBuffer m_path; __int64 m_size;
// Do we actually have valid hashing data?
bool m_bHasHashInfo; CStringBuffer m_HashString; ALG_ID m_HashAlgorithm;
private: CFusionFilePathAndSize(const CFusionFilePathAndSize &); // intentionally not implemented
void operator =(const CFusionFilePathAndSize &); // intentionally not implemented
};
/*-----------------------------------------------------------------------------
two DWORDs to an __int64 -----------------------------------------------------------------------------*/ ULONGLONG FusionpFileSizeFromFindData( const WIN32_FIND_DATAW& wfd );
/*-----------------------------------------------------------------------------
HRESULT_FROM_WIN32(GetLastError()) or E_FAIL if GetLastError() == NO_ERROR -----------------------------------------------------------------------------*/ HRESULT FusionpHresultFromLastError();
/*-----------------------------------------------------------------------------
FindFirstFile results you always ignore "." and ".." -----------------------------------------------------------------------------*/ BOOL FusionpIsDotOrDotDot(PCWSTR str);
/*-----------------------------------------------------------------------------
simple code for walking directories, with a per file callback could be fleshed out more, but good enough for present purposes -----------------------------------------------------------------------------*/
#define SXSP_DIR_WALK_FLAGS_FIND_AT_LEAST_ONE_FILEUNDER_CURRENTDIR (1)
#define SXSP_DIR_WALK_FLAGS_INSTALL_ASSEMBLY_UNDER_CURRECTDIR_SUCCEED (2)
class CDirWalk { public: enum ECallbackReason { eBeginDirectory = 1, eFile, eEndDirectory };
CDirWalk();
//
// the callback cannot reenable what is has disabled
// perhaps move these to be member data bools
//
enum ECallbackResult { eKeepWalking = 0x00000000, eError = 0x00000001, eSuccess = 0x00000002, eStopWalkingFiles = 0x00000004, eStopWalkingDirectories = 0x00000008, eStopWalkingDeep = 0x00000010 };
//
// Just filter on like *.dll, in the future you can imagine
// filtering on attributes like read onlyness, or running
// SQL queries over the "File System Oledb Provider"...
//
// Also, note that we currently do a FindFirstFile/FindNextFile
// loop for each filter, plus sometimes one more with *
// to pick up directories. It is probably more efficient to
// use * and then filter individually but I don't feel like
// porting over \Vsee\Lib\Io\Wildcard.cpp right now (which
// was itself ported from FsRtl, and should be in Win32!)
//
const PCWSTR* m_fileFiltersBegin; const PCWSTR* m_fileFiltersEnd; CStringBuffer m_strParent; // set this to the initial directory to walk
SIZE_T m_cchOriginalPath; WIN32_FIND_DATAW m_fileData; // not valid for directory callbacks, but could be with a little work
PVOID m_context;
CStringBuffer m_strLastObjectFound;
ECallbackResult (*m_callback)( ECallbackReason reason, CDirWalk* dirWalk, DWORD dwWalkDirFlags );
BOOL Walk();
protected: ECallbackResult WalkHelper();
private: CDirWalk(const CDirWalk &); // intentionally not implemented
void operator =(const CDirWalk &); // intentionally not implemented
};
ENUM_BIT_OPERATIONS(CDirWalk::ECallbackResult)
/*-----------------------------------------------------------------------------*/
typedef struct _FUSION_FLAG_FORMAT_MAP_ENTRY { DWORD m_dwFlagMask; PCWSTR m_pszString; SIZE_T m_cchString; PCWSTR m_pszShortString; SIZE_T m_cchShortString; DWORD m_dwFlagsToTurnOff; // enables more generic flags first in map hiding more specific combinations later
} FUSION_FLAG_FORMAT_MAP_ENTRY, *PFUSION_FLAG_FORMAT_MAP_ENTRY;
#define DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(_x, _ss) { _x, L ## #_x, NUMBER_OF(L ## #_x) - 1, L ## _ss, NUMBER_OF(_ss) - 1, _x },
typedef const FUSION_FLAG_FORMAT_MAP_ENTRY *PCFUSION_FLAG_FORMAT_MAP_ENTRY;
BOOL FusionpFormatFlags( IN DWORD dwFlagsToFormat, IN bool fUseLongNames, IN SIZE_T cMapEntries, IN PCFUSION_FLAG_FORMAT_MAP_ENTRY prgMapEntries, IN OUT CBaseStringBuffer &rbuff );
/*-----------------------------------------------------------------------------
inline implementations -----------------------------------------------------------------------------*/ inline BOOL FusionpIsPathSeparator( WCHAR ch ) /*
NTRAID#NTBUG9-591195-2002/03/31-JayKrell path issues, case mapping.. (but this is probably ok) */ { return ((ch == L'\\') || (ch == L'/')); }
inline BOOL FusionpIsDotOrDotDot( PCWSTR str ) /*
NTRAID#NTBUG9-591195-2002/03/31-JayKrell path issues, case mapping.. */ { return ((str[0] == L'.') && ((str[1] == L'\0') || ((str[1] == L'.') && (str[2] == L'\0')))); }
inline BOOL FusionpIsDriveLetter( WCHAR ch ) /*
NTRAID#NTBUG9-591195-2002/03/31-JayKrell path issues, case mapping.. */ { if (ch >= L'a' && ch <= L'z') return TRUE; if (ch >= L'A' && ch <= L'Z') return TRUE; return FALSE; }
inline ULONGLONG FusionpFileSizeFromFindData( const WIN32_FIND_DATAW& wfd ) { ULARGE_INTEGER uli;
uli.LowPart = wfd.nFileSizeLow; uli.HighPart = wfd.nFileSizeHigh;
return uli.QuadPart; }
inline HRESULT FusionpHresultFromLastError() { HRESULT hr = E_FAIL; DWORD dwLastError = ::FusionpGetLastWin32Error(); if (dwLastError != NO_ERROR) { hr = HRESULT_FROM_WIN32(dwLastError); } return hr; }
template <> inline BOOL FusionWin32CopyContents<CFusionFilePathAndSize>( CFusionFilePathAndSize& rtDestination, const CFusionFilePathAndSize& rtSource ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); IFW32FALSE_EXIT(rtDestination.m_path.Win32Assign(rtSource.m_path, rtSource.m_path.Cch())); IFW32FALSE_EXIT(rtDestination.m_HashString.Win32Assign(rtSource.m_HashString, rtSource.m_HashString.Cch())); rtDestination.m_size = rtSource.m_size; rtDestination.m_HashAlgorithm = rtSource.m_HashAlgorithm; rtDestination.m_bHasHashInfo = rtSource.m_bHasHashInfo; fSuccess = TRUE; Exit: return fSuccess; }
#define FUSIONP_REG_QUERY_SZ_VALUE_EX_MISSING_GIVES_NULL_STRING (0x00000001)
#define FUSIONP_REG_QUERY_DWORD_MISSING_VALUE_IS_FAILURE (0x00000001)
#define FUSIONP_REG_QUERY_BINARY_NO_FAIL_IF_NON_BINARY (0x00000001)
BOOL FusionpRegQuerySzValueEx( DWORD dwFlags, HKEY hKey, PCWSTR lpValueName, CBaseStringBuffer &Buffer, DWORD &rdwWin32Error, SIZE_T cExceptionalLastErrorValues, ... );
BOOL FusionpRegQuerySzValueEx( DWORD dwFlags, HKEY hKey, PCWSTR lpValueName, CBaseStringBuffer &Buffer );
BOOL FusionpRegQueryDwordValueEx( DWORD dwFlags, HKEY hKey, PCWSTR wszValueName, PDWORD pdwValue, DWORD dwDefaultValue = 0 );
BOOL FusionpRegQueryBinaryValueEx( DWORD dwFlags, HKEY hKey, PCWSTR lpValueName, CFusionArray<BYTE> &rbBuffer );
BOOL FusionpRegQueryBinaryValueEx( DWORD dwFlags, HKEY hKey, PCWSTR lpValueName, CFusionArray<BYTE> &rbBuffer, DWORD &rdwLastError, SIZE_T cExceptionalLastErrors, ... );
BOOL FusionpRegQueryBinaryValueEx( DWORD dwFlags, HKEY hKey, PCWSTR lpValueName, CFusionArray<BYTE> &rbBuffer, DWORD &rdwLastError, SIZE_T cExceptionalLastErrors, va_list ap );
BOOL FusionpAreWeInOSSetupMode( BOOL* );
BOOL FusionpAreWeInMiniSetupMode( BOOL* );
BOOL FusionpMapLangIdToString( DWORD dwFlags, LANGID LangID, PCWSTR *StringOut );
BOOL SxspDequoteString( IN DWORD dwFlags, IN PCWSTR pcwszStringIn, IN SIZE_T cchStringIn, OUT PWSTR pwszStringOut, OUT SIZE_T *pcchStringOut );
BOOL FusionpGetActivationContextFromFindResult( IN PCACTCTX_SECTION_KEYED_DATA askd, OUT HANDLE * );
#define FUSIONP_SEARCH_PATH_ACTCTX (0x00000001)
BOOL FusionpSearchPath( ULONG ulFusionFlags, LPCWSTR lpPath, LPCWSTR lpFileName, // file name
LPCWSTR lpExtension, // file extension
CBaseStringBuffer & StringBuffer, SIZE_T * lpFilePartOffset, // file component
HANDLE hActCtx );
BOOL FusionpGetModuleFileName( ULONG ulFusionFlags, HMODULE hmodDll, CBaseStringBuffer & StringBuffer );
#define SXSP_DOES_FILE_EXIST_FLAG_COMPRESSION_AWARE (0x00000001)
#define SXSP_DOES_FILE_EXIST_FLAG_INCLUDE_NETWORK_ERRORS (0x00000002)
#define SXSP_DOES_FILE_EXIST_FLAG_CHECK_FILE_ONLY (0x00000004)
#define SXSP_DOES_FILE_EXIST_FLAG_CHECK_DIRECTORY_ONLY (0x00000008)
BOOL SxspDoesFileExist( DWORD dwFlags, PCWSTR pszFileName, bool &rfExists );
#define SXSP_DOES_FILE_OR_DIRECTORY_EXIST_FLAG_COMPRESSION_AWARE (0x00000001)
#define SXSP_DOES_FILE_OR_DIRECTORY_EXIST_FLAG_INCLUDE_NETWORK_ERRORS (0x00000002)
#define SXSP_DOES_FILE_OR_DIRECTORY_EXIST_DISPOSITION_FILE_EXISTS (1)
#define SXSP_DOES_FILE_OR_DIRECTORY_EXIST_DISPOSITION_DIRECTORY_EXISTS (2)
#define SXSP_DOES_FILE_OR_DIRECTORY_EXIST_DISPOSITION_NEITHER_EXISTS (3)
BOOL SxspDoesFileOrDirectoryExist( DWORD dwFlags, PCWSTR pszFileName, OUT DWORD &rdwDisposition );
BOOL SxspGetFileAttributesW( PCWSTR lpFileName, DWORD &rdwFileAttributes );
BOOL SxspGetFileAttributesW( PCWSTR lpFileName, DWORD &rdwFileAttributes, DWORD &rdwWin32Error, SIZE_T cExceptionalWin32Errors, ... );
BOOL SxspFormatULONG( ULONG ul, SIZE_T CchBuffer, WCHAR Buffer[], SIZE_T *CchWrittenOrRequired );
#pragma warning(pop)
#endif
|