////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Header
#include "Define.h"
#include "UniBase.h"
#include "Resource.h"
#include <ShlObj.h>
#pragma comment(lib, "ShLwAPI.lib")
HINSTANCE g_hInst = NULL;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Execute command
BOOL Exec(PTSTR ptzCmd, PCTSTR ptzDir = NULL)
{
STARTUPINFO si = {0};
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
BOOL bResult = CreateProcess(NULL, ptzCmd, NULL, NULL, FALSE, 0, NULL, ptzDir, &si, &pi);
if (bResult)
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
return bResult;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Parse INF for BartPE & XCMD
template <typename T1, typename T2> inline BOOL TStrEqual(T1 ptStr1, T2 ptStr2, UINT uLen)
{
for (UINT i = 0; i < uLen; i++)
{
if (!UChrEqual((TCHAR) ptStr1[i], (TCHAR) ptStr2[i]))
{
return FALSE;
}
}
return TRUE;
}
template <typename T1, typename T2> PVOID TStrStr(T1 ptStr1, T2 ptStr2, UINT uLen)
{
for (T1 p = ptStr1; *p; p++)
{
if (TStrEqual(ptStr1, ptStr2, uLen))
{
return p;
}
}
return NULL;
}
#define _InfRep(s) if (TStrEqual(p, TEXT(s), sizeof(s) - 1)) {p[1] = ';'; p += sizeof(s); bRep = TRUE;}
template <typename T> UINT TRepInf(T ptData)
{
T p = ptData;
BOOL bRep = FALSE;
for (; *p; p++)
{
_InfRep("\nCopyFiles")
else _InfRep("\nDelFiles")
else _InfRep("\nUpdateInis")
else _InfRep("\nDelDirs")
else _InfRep("\nRenFiles")
}
return bRep;
}
BOOL XINF(PCTSTR ptzPath)
{
HANDLE hFile = UFileOpen(ptzPath, UFILE_ALL);
if (!hFile)
{
return FALSE;
}
PBYTE pbFile;
UINT uSize = GetFileSize(hFile, NULL);
HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, uSize, NULL);
if (!hMapping || !(pbFile = (PBYTE) MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0)))
{
UFileClose(hFile);
return FALSE;
}
pbFile[3] ? TRepInf((PSTR) pbFile) : TRepInf((PWSTR) pbFile);
UnmapViewOfFile(pbFile);
CloseHandle(hMapping);
UFileClose(hFile);
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Search file
PTSTR XDIR(PCTSTR ptzDir, PTSTR ptzBuf, BOOL bInf)
{
HANDLE hFind;
WIN32_FIND_DATA fd;
TCHAR tzFind[MAX_PATH];
UStrPrint(tzFind, TEXT("%s\\*"), ptzDir);
if ((hFind = FindFirstFile(tzFind, &fd)) == INVALID_HANDLE_VALUE)
{
return ptzBuf;
}
PTSTR ptzInf = ptzBuf;
do
{
if (fd.cFileName[0] != '.')
{
UStrPrint(tzFind, TEXT("%s\\%s"), ptzDir, fd.cFileName);
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
ptzBuf = XDIR(tzFind, ptzBuf, bInf);
}
else
{
if (bInf && (UStrCmpI(tzFind + UStrLen(tzFind) - 4, TEXT(".INF")) == 0))
{
XINF(tzFind);
if (ptzBuf != ptzInf)
{
UStrCopy(ptzBuf, ptzInf);
}
UStrCopy(ptzInf, tzFind);
ptzInf += MAX_PATH;
}
else
{
UStrCopy(ptzBuf, tzFind);
}
ptzBuf += MAX_PATH;
}
}
}
while (FindNextFile(hFind, &fd));
FindClose(hFind);
return ptzBuf;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Compress CAB
#define STR_DDF \
TEXT(".OPTION EXPLICIT\r\n") \
TEXT(".Set Cabinet=on\r\n") \
TEXT(".Set Compress=on\r\n") \
TEXT(".Set CompressionType=LZX\r\n") \
TEXT(".Set CompressionMemory=%d\r\n") \
TEXT(".Set MaxDiskSize=0\r\n") \
TEXT(".Set FolderSizeThreshold=2147483648\r\n") \
TEXT(".Set UniqueFiles=OFF\r\n") \
TEXT(".Set DestinationDir=\r\n") \
TEXT(".Set DiskDirectoryTemplate=.\r\n") \
TEXT(".Set InfFileName=%sXCAB.inf\r\n") \
TEXT(".Set RptFileName=%sXCAB.rpt\r\n") \
TEXT(".Set CabinetName1=%s\r\n")
BOOL XCAB(PTSTR ptzSrc, PTSTR ptzDst, UINT uRatio = 21, BOOL bInf = FALSE)
{
TCHAR tzCmd[MAX_STR];
PTSTR ptzName = UDirSplitPath(ptzDst);
if (!UDirExist(ptzSrc))
{
UStrPrint(tzCmd, TEXT("MakeCab.exe /v2 /D CompressionType=LZX /D CompressionMemory=%d \"%s\" \"%s\""), uRatio, ptzSrc, ptzName);
}
else
{
PTSTR ptzBuf = (PTSTR) UMemAlloc(10240 * MAX_PATH);
if (!ptzBuf) return FALSE;
TCHAR tzPath[MAX_PATH];
GetTempPath(MAX_PATH, tzPath);
UINT uSize = UStrPrint(ptzBuf, STR_DDF, uRatio, tzPath, tzPath, ptzName);
UStrCat(tzPath, TEXT("XCAB.ddf"));
UStrPrint(tzCmd, TEXT("MakeCab.exe /f \"%s\""), tzPath);
HANDLE hFile = UFileOpen(tzPath, UFILE_WRITE);
if (hFile)
{
UFileWrite(hFile, ptzBuf, uSize * sizeof(TCHAR));
UINT uDir = UStrLen(ptzSrc) + 1;
PTSTR ptzEnd = XDIR(ptzSrc, ptzBuf, bInf);
for (PTSTR p = ptzBuf; p < ptzEnd; p += MAX_PATH)
{
UINT i = sizeof(TCHAR) * UStrPrint(tzPath, TEXT("\"%s\" \"%s\"\r\n"), p, p + uDir);
UFileWrite(hFile, tzPath, i);
}
UFileClose(hFile);
}
UMemFree(ptzBuf);
}
if (ptzName[-2] == ':')
{
ptzName[-1] = '\\';
ptzName[0] = 0;
}
return Exec(tzCmd, ptzDst);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Browse folder callback
INT CALLBACK BrowseDirProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
if (uMsg == BFFM_INITIALIZED)
{
SendMessage(hWnd, BFFM_SETSELECTION, TRUE, lpData);
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Browse folder
BOOL BrowseFolder(PTSTR ptzFolder, PCTSTR ptzTitle = NULL, HWND hParent = NULL)
{
BROWSEINFO bi = {0};
bi.hwndOwner = hParent;
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS;
bi.lpszTitle = ptzTitle;
bi.lpfn = BrowseDirProc;
bi.lParam = (LPARAM) ptzFolder;
LPITEMIDLIST p = SHBrowseForFolder(&bi);
if (!p)
{
return FALSE;
}
BOOL bResult = SHGetPathFromIDList(p, ptzFolder);
LPMALLOC pMalloc;
if (SUCCEEDED(SHGetMalloc(&pMalloc)))
{
pMalloc->Free(p);
pMalloc->Release();
}
return bResult;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Main window
#include "Reg.h"
#pragma warning(disable:4244)
INT_PTR CALLBACK MainDlgProc(HWND hWnd, UI