Windows2000/private/windbg64/dbgwiz/copydlg.cpp

484 lines
13 KiB
C++

#include "precomp.hxx"
#pragma hdrstop
typedef
class LIST_OF_FILES_IN_DIR {
public:
char m_szDirPath[_MAX_PATH * 2];
TList<PSTR> m_listFileNames;
LIST_OF_FILES_IN_DIR() { ZeroMemory(m_szDirPath, sizeof(m_szDirPath)); }
~LIST_OF_FILES_IN_DIR();
} * PLIST_OF_FILES_IN_DIR;
LIST_OF_FILES_IN_DIR::
~LIST_OF_FILES_IN_DIR()
{
while (!m_listFileNames.IsEmpty()) {
free( m_listFileNames.GetHeadData() );
m_listFileNames.RemoveHead();
}
}
// The friggin error handling bloated these functions
BOOL
GetListOfFiles(
long & lStopCopying,
PSTR pszPath,
TList<PLIST_OF_FILES_IN_DIR> & ListOfDirectories,
DWORD & dwTotalFilesToCopy
)
{
BOOL bRet = TRUE;
char szTmpCurPath[_MAX_PATH * 2];
PLIST_OF_FILES_IN_DIR pListOfFiles = new LIST_OF_FILES_IN_DIR;
Assert(pListOfFiles);
ListOfDirectories.InsertTail(pListOfFiles);
//
// Record current directory path
//
strcpy(pListOfFiles->m_szDirPath, pszPath);
strcat(pListOfFiles->m_szDirPath, "\\");
Assert(strlen(pListOfFiles->m_szDirPath) < sizeof(pListOfFiles->m_szDirPath));
//
// Build search path
//
strcpy(szTmpCurPath, pListOfFiles->m_szDirPath);
strcat(szTmpCurPath, "*");
Assert(strlen(szTmpCurPath) < sizeof(szTmpCurPath));
WIN32_FIND_DATA wfd;
HANDLE hFindFile = FindFirstFile(szTmpCurPath, &wfd);
BOOL bContinue = (INVALID_HANDLE_VALUE != hFindFile);
while (bContinue) {
if (InterlockedExchangeAdd(&lStopCopying, 0)) {
// user pressed cancel, stop searching
bRet = FALSE;
goto EXIT;
}
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (strcmp(".", wfd.cFileName) && strcmp("..", wfd.cFileName)) {
//
// We found a new dir, build the path and recurse into it.
//
strcpy(szTmpCurPath, pListOfFiles->m_szDirPath);
strcat(szTmpCurPath, wfd.cFileName);
Assert(strlen(szTmpCurPath) < sizeof(szTmpCurPath));
if (!GetListOfFiles(lStopCopying, szTmpCurPath, ListOfDirectories, dwTotalFilesToCopy)) {
// user pressed cancel, stop searching
bRet = FALSE;
goto EXIT;
}
}
} else {
//
// Found a file, inc the counter
//
dwTotalFilesToCopy++;
PSTR pszNewFile = NT4SafeStrDup(wfd.cFileName);
Assert(pszNewFile);
pListOfFiles->m_listFileNames.InsertTail(pszNewFile);
}
bContinue = FindNextFile(hFindFile, &wfd);
}
EXIT:
if (INVALID_HANDLE_VALUE != hFindFile) {
Assert(FindClose(hFindFile));
}
return bRet;
}
BOOL
DecompressCopyFile(
HWND hwndDlg,
PSTR pszDestPath,
PSTR pszSrcPath,
PSTR pszSrcFile,
BOOL & bWarnAboutUnknownFiles
)
{
//
// Let's figure out the destination name
//
const int nNumSyms = 3;
PSTR rgpszSymExtensions[nNumSyms][2] = {
{ ".PDB", ".PD_" },
{ ".DBG", ".DB_" },
{ ".SYM", ".SY_" }
};
// Get the file name and extensions
char szName[_MAX_FNAME];
char szExt[_MAX_EXT];
_splitpath(pszSrcFile, NULL, NULL, szName, szExt);
// Figure out the expanded extension
for (int i=0; i<nNumSyms; i++) {
if (!_stricmp(szExt, rgpszSymExtensions[i][0])) {
// The extension is not compressed
goto FILE_NAME_FOUND;
} else if (!_stricmp(szExt, rgpszSymExtensions[i][1])) {
// Expand the extension
strcpy(szExt, rgpszSymExtensions[i][0]);
goto FILE_NAME_FOUND;
}
}
//
// The extension name was not found, should we warn the user
//
if (bWarnAboutUnknownFiles) {
PSTR pszErr = WKSP_DynaLoadStringWithArgs(g_hInst, IDS_WARN_NOT_A_SYMBOL, pszSrcFile);
PSTR pszWarning = WKSP_DynaLoadString(g_hInst, IDS_WARNING);
int nRes = MessageBox(NULL, pszErr, pszWarning, MB_TASKMODAL | MB_YESNOCANCEL | MB_ICONEXCLAMATION);
if (IDCANCEL == nRes) {
return FALSE;
} else if (IDNO == nRes) {
bWarnAboutUnknownFiles = FALSE;
}
free(pszWarning);
free(pszErr);
}
//
// Build the src and dest paths
//
FILE_NAME_FOUND:
BOOL bResult = TRUE;
char szSrc[_MAX_PATH * 2];
strcpy(szSrc, pszSrcPath);
strcat(szSrc, pszSrcFile);
Assert(strlen(szSrc) < sizeof(szSrc));
char szDest[_MAX_PATH * 2];
strcpy(szDest, pszDestPath);
strcat(szDest, szName);
strcat(szDest, szExt);
Assert(strlen(szDest) < sizeof(szDest));
//
// Decompress copy the file
//
RETRY_COPY:
if (ERROR_SUCCESS != SetupDecompressOrCopyFile(szSrc, szDest, NULL)) {
PSTR pszErr = WKSP_DynaLoadStringWithArgs(g_hInst, IDS_ERR_COPYING_SYMBOL, szSrc, szDest);
Assert(pszErr);
int nRes = MessageBox(NULL, pszErr, NULL, MB_TASKMODAL | MB_ICONSTOP | MB_ABORTRETRYIGNORE);
if (IDABORT == nRes) {
bResult = FALSE;
goto EXIT;
} else if (IDRETRY == nRes) {
goto RETRY_COPY;
} else if (IDIGNORE == nRes) {
bResult = TRUE;
}
}
EXIT:
return bResult;
}
BOOL
CopyDirectory(
long & lStopCopying,
HWND hwndDlg,
HWND hwndProgress,
HWND hwndCurFile,
DWORD & dwFilesCopied,
const DWORD dwTotalFilesToCopy,
PSTR pszOrigDestPath,
PSTR pszOrigSrcPath,
LIST_OF_FILES_IN_DIR & ListOfFiles,
BOOL & bWarnAboutUnknownFiles
)
{
Assert(hwndDlg);
Assert(hwndProgress);
Assert(hwndCurFile);
Assert(!_strnicmp(ListOfFiles.m_szDirPath, pszOrigSrcPath, strlen(pszOrigSrcPath)));
// Point
PSTR psz = ListOfFiles.m_szDirPath + strlen(pszOrigSrcPath);
char szDestPath[_MAX_PATH * 2] = {0};
strcpy(szDestPath, pszOrigDestPath);
strcat(szDestPath, psz);
Assert(strlen(szDestPath) < sizeof(szDestPath));
RETRY_DIR_CREATION:
if (!CreateDirIfNotExist(szDestPath)) {
int nRes = WKSP_CustMsgBox(MB_ICONHAND | MB_TASKMODAL | MB_ABORTRETRYIGNORE,
NULL, IDS_ERROR_CANT_CREATE_DIR, szDestPath);
if (IDABORT == nRes) {
return FALSE;
} else if (IDRETRY == nRes) {
goto RETRY_DIR_CREATION;
} else if (IDIGNORE == nRes) {
// was copied but, we need to increment the progress bar
dwFilesCopied += ListOfFiles.m_listFileNames.Size();
return TRUE;
} else {
Assert(0);
}
}
while (!ListOfFiles.m_listFileNames.IsEmpty()) {
// Don't modify it, just test it
if (InterlockedExchangeAdd(&lStopCopying, 0)) {
// user pressed cancel
// stop copying
return FALSE;
}
// Give UI feedback
PSTR pszFileName = ListOfFiles.m_listFileNames.GetHeadData();
ListOfFiles.m_listFileNames.RemoveHead();
{
char sz[_MAX_PATH * 2];
strcpy(sz, ListOfFiles.m_szDirPath);
strcat(sz, pszFileName);
Assert(strlen(sz) < sizeof(sz));
SendMessage(hwndCurFile, WM_SETTEXT, 0, (LPARAM) sz);
}
// Actually copy
if (!DecompressCopyFile(hwndDlg, szDestPath, ListOfFiles.m_szDirPath, pszFileName, bWarnAboutUnknownFiles)) {
// Abort copying
return FALSE;
}
dwFilesCopied++;
PostMessage(hwndProgress, PBM_SETPOS, USHRT_MAX * dwFilesCopied / dwTotalFilesToCopy, 0);
free(pszFileName);
}
// Continue copying
return TRUE;
}
DWORD
WINAPI
CopySymbols(
PVOID pvParam
)
{
BOOL bWarnAboutUnknownFiles = TRUE;
DWORD dwFilesCopied = 0;
Assert(pvParam);
PCOPY_SYMBOLS_DATA_STRUCT pCopySymsData = (PCOPY_SYMBOLS_DATA_STRUCT) pvParam;
Assert(pCopySymsData->m_hwndDlgParent);
{
PSTR psz = pCopySymsData->m_szSrcPath + strlen(pCopySymsData->m_szSrcPath) -1;
if ('\\' == *psz) {
*psz = NULL;
}
psz = pCopySymsData->m_szDestPath + strlen(pCopySymsData->m_szDestPath) -1;
if ('\\' == *psz) {
*psz = NULL;
}
}
HWND hwndProgress = GetDlgItem(pCopySymsData->m_hwndDlgParent, IDC_PROGRESS);
Assert(hwndProgress);
HWND hwndCurFile = GetDlgItem(pCopySymsData->m_hwndDlgParent, IDC_STATIC_CURRENT_FILE);
Assert(hwndCurFile);
SendMessage(hwndProgress, PBM_SETPOS, 0, 0);
SendMessage(hwndProgress, PBM_SETRANGE, 0, MAKELPARAM(0, USHRT_MAX));
// Get the list of files, and the total size in files to copy.
TList<PLIST_OF_FILES_IN_DIR> ListOfDirectories;
DWORD dwTotalFilesToCopy = 0;
if (!GetListOfFiles(pCopySymsData->m_lStopCopying, pCopySymsData->m_szSrcPath,
ListOfDirectories, dwTotalFilesToCopy)) {
// User canceled
goto EXIT;
}
// Did we find any files to copy
if (0 == dwTotalFilesToCopy) {
WKSP_MsgBox(NULL, IDS_ERROR_NO_FILES_FOUND);
// simulate the user pressing cancel
InterlockedExchange(&pCopySymsData->m_lStopCopying, TRUE);
goto EXIT;
}
RETRY_DIR_CREATION:
if (!CreateDirTree(pCopySymsData->m_szDestPath)) {
int nRes = WKSP_CustMsgBox(MB_ICONHAND | MB_TASKMODAL | MB_RETRYCANCEL,
NULL, IDS_ERROR_RETRYCANCEL_CANT_CREATE_DIR, pCopySymsData->m_szDestPath);
if (IDRETRY == nRes) {
goto RETRY_DIR_CREATION;
} else if (IDCANCEL == nRes) {
goto EXIT;
} else {
Assert(0);
}
}
// If the symbols are being copied from \\ntstress assume that are files
// copied are correct. Do not warn about any of the files.
{
PSTR psz = "\\\\ntstress";
if (!_strnicmp(pCopySymsData->m_szSrcPath, psz, strlen(psz))) {
bWarnAboutUnknownFiles = FALSE;
} else {
bWarnAboutUnknownFiles = TRUE;
}
}
dwFilesCopied = 0;
while (!ListOfDirectories.IsEmpty()) {
PLIST_OF_FILES_IN_DIR pListOfDirectories = ListOfDirectories.GetHeadData();
ListOfDirectories.RemoveHead();
Assert(pListOfDirectories);
if (!CopyDirectory(pCopySymsData->m_lStopCopying, pCopySymsData->m_hwndDlgParent, hwndProgress,
hwndCurFile, dwFilesCopied, dwTotalFilesToCopy,
pCopySymsData->m_szDestPath, pCopySymsData->m_szSrcPath,
*pListOfDirectories, bWarnAboutUnknownFiles)) {
// Copying aborted
delete pListOfDirectories;
goto EXIT;
}
delete pListOfDirectories;
}
EXIT:
if (InterlockedExchangeAdd(&pCopySymsData->m_lStopCopying, 0)) {
PostMessage(pCopySymsData->m_hwndDlgParent, UM_FINISHED_ENDDIALOG, 0, IDCANCEL);
} else {
PostMessage(pCopySymsData->m_hwndDlgParent, UM_FINISHED_ENDDIALOG, 0, IDOK);
}
return 0;
}
INT_PTR
CALLBACK
Copying_DlgProc(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
PCOPY_SYMBOLS_DATA_STRUCT pCopySymsData;
pCopySymsData = (PCOPY_SYMBOLS_DATA_STRUCT) GetWindowLongPtr(hDlg, DWLP_USER);
switch (uMsg) {
case WM_DESTROY:
Assert(pCopySymsData);
ZeroMemory(pCopySymsData, sizeof(COPY_SYMBOLS_DATA_STRUCT));
pCopySymsData = NULL;
return FALSE;
case WM_INITDIALOG:
pCopySymsData = (PCOPY_SYMBOLS_DATA_STRUCT) lParam;
Assert(pCopySymsData);
pCopySymsData->m_hwndDlgParent = hDlg;
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pCopySymsData);
PostMessage(hDlg, UM_STARTCOPYING, 0, 0);
return TRUE;
case UM_STARTCOPYING:
{
// TODO: Add your control notification handler code here
DWORD dwThreadId;
HANDLE hThread = CreateThread(
NULL, // no security attributes
0, // use default stack size
CopySymbols, // thread function
pCopySymsData, // argument to thread function
0, // use default creation flags
&dwThreadId); // returns the thread identifier
// Check the return value for success.
Assert(hThread);
CloseHandle(hThread);
return TRUE;
}
case UM_FINISHED_ENDDIALOG:
EndDialog(hDlg, lParam);
return FALSE;
case WM_COMMAND:
{
WORD wNotifyCode = HIWORD(wParam); // notification code
WORD wID = LOWORD(wParam); // item, control, or accelerator identifier
HWND hwndCtl = (HWND) lParam; // handle of control
if (hwndCtl) {
switch (wID) {
case IDCANCEL:
InterlockedExchange(&pCopySymsData->m_lStopCopying, TRUE);
// Give the user feedback that cancel has been pressed,
// because the user may think that something is wrong since it doesn't
// stop immediately but waits until the current file copy has finished.
EnableWindow(hwndCtl, FALSE);
PSTR psz = WKSP_DynaLoadString(g_hInst, IDS_STOPPING);
SetWindowText(hwndCtl, psz);
free(psz);
return TRUE;
}
}
}
return FALSE;
}
return FALSE;
}