Exemple #1
0
/// Saves given path to registry for ShellExtension, and Context Menu settings
void PropShell::SaveMergePath()
{
	TCHAR temp[MAX_PATH] = {0};
	LONG retVal = 0;
	GetModuleFileName(AfxGetInstanceHandle(), temp, MAX_PATH);

	CRegKeyEx reg;
	retVal = reg.Open(HKEY_CURRENT_USER, f_RegDir);
	if (retVal != ERROR_SUCCESS)
	{
		CString msg;
		msg.Format(_T("Failed to open registry key HKCU/%s:\n\t%d : %s"),
			f_RegDir, retVal, GetSysError(retVal).c_str());
		LogErrorString(msg);
		return;
	}

	// Save path to WinMerge(U).exe
	retVal = reg.WriteString(f_RegValuePath, temp);
	if (retVal != ERROR_SUCCESS)
	{
		CString msg;
		msg.Format(_T("Failed to set registry value %s:\n\t%d : %s"),
			f_RegValuePath, retVal, GetSysError(retVal).c_str());
		LogErrorString(msg);
	}

	// Determine bitmask for shell extension
	DWORD dwContextEnabled = reg.ReadDword(f_RegValueEnabled, 0);
	if (m_bContextAdded)
		dwContextEnabled |= CONTEXT_F_ENABLED;
	else
		dwContextEnabled &= ~CONTEXT_F_ENABLED;

	if (m_bContextAdvanced)
		dwContextEnabled |= CONTEXT_F_ADVANCED;
	else
		dwContextEnabled &= ~CONTEXT_F_ADVANCED;

	if (m_bContextSubfolders)
		dwContextEnabled |= CONTEXT_F_SUBFOLDERS;
	else
		dwContextEnabled &= ~CONTEXT_F_SUBFOLDERS;

	retVal = reg.WriteDword(f_RegValueEnabled, dwContextEnabled);
	if (retVal != ERROR_SUCCESS)
	{
		CString msg;
		msg.Format(_T("Failed to set registry value %s to %d:\n\t%d : %s"),
			f_RegValueEnabled, dwContextEnabled, retVal, GetSysError(retVal).c_str());
		LogErrorString(msg);
	}
}
Exemple #2
0
/// Get registry values for ShellExtension
void PropShell::GetContextRegValues()
{
	CRegKeyEx reg;
	LONG retVal = 0;
	retVal = reg.Open(HKEY_CURRENT_USER, f_RegDir);
	if (retVal != ERROR_SUCCESS)
	{
		CString msg;
		msg.Format(_T("Failed to open registry key HKCU/%s:\n\t%d : %s"),
			f_RegDir, retVal, GetSysError(retVal).c_str());
		LogErrorString(msg);
		return;
	}

	// Read bitmask for shell extension settings
	DWORD dwContextEnabled = reg.ReadDword(f_RegValueEnabled, 0);

	if (dwContextEnabled & CONTEXT_F_ENABLED)
		m_bContextAdded = TRUE;

	if (dwContextEnabled & CONTEXT_F_ADVANCED)
		m_bContextAdvanced = TRUE;

	if (dwContextEnabled & CONTEXT_F_SUBFOLDERS)
		m_bContextSubfolders = TRUE;
}
Exemple #3
0
/*! \brief Determine the type of cable (XA1541/XM1541) on the IEC bus

 This function tries to determine the type of cable with which
 the IEC bus is connected to the PC's parallel port. Afterwards,
 some variables in the device extension are initialized to reflect
 the type.

 \param Pdx
   Pointer to the device extension.

 \return 
   If the routine succeeds, it returns STATUS_SUCCESS. Otherwise, it
   returns one of the error status values.

 \todo
   Do a more sophisticated test
*/
static NTSTATUS
cbmiec_testcable(PDEVICE_EXTENSION Pdx) 
{
    const wchar_t *msgAuto = L"";
    const wchar_t *msgCable;
    UCHAR in, out;

    FUNC_ENTER();

/*! \todo Do a more sophisticated test for the cable */

    switch (Pdx->IecCable)
    {
    case IEC_CABLETYPE_XM:
        /* FALL THROUGH */

    case IEC_CABLETYPE_XA:
        break;

    default:
        in = CBMIEC_GET(PP_ATN_IN);
        out = (READ_PORT_UCHAR(OUT_PORT) & PP_ATN_OUT) ? 1 : 0;
        Pdx->IecCable = (in != out) ? IEC_CABLETYPE_XA : IEC_CABLETYPE_XM;
        msgAuto = L" (auto)";
        break;
    }

    switch (Pdx->IecCable)
    {
    case IEC_CABLETYPE_XM:
        msgCable = L"passive (XM1541)";
        break;

    case IEC_CABLETYPE_XA:
        msgCable = L"active (XA1541)";
        break;
    }

    Pdx->IecOutEor = Pdx->IecCable ? 0xcb : 0xc4;

    DBG_SUCCESS((DBG_PREFIX "using %ws cable%ws",
        Pdx->IecCable ? L"active (XA1541)" : L"passive (XM1541)",
        msgAuto));

    LogErrorString(Pdx->Fdo, CBM_IEC_INIT, msgCable, msgAuto);

    Pdx->IecOutBits = (READ_PORT_UCHAR(OUT_PORT) ^ Pdx->IecOutEor) 
                      & (PP_DATA_OUT|PP_CLK_OUT|PP_ATN_OUT|PP_RESET_OUT);

/*
    if (Pdx->IecOutBits & PP_RESET_OUT)
    {
       cbmiec_reset(Pdx);
    }
*/

    FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
}
// for OLECHAR files, transform to UTF8 for diffutils
// TODO : convert Ansi to UTF8 if other file is unicode or uses a different codepage
BOOL FileTransform_UCS2ToUTF8(String & filepath, BOOL bMayOverwrite)
{
	String tempDir = env_GetTempPath();
	if (tempDir.empty())
		return FALSE;
	String tempFilepath = env_GetTempFileName(tempDir.c_str(), _T("_WM"));
	if (tempFilepath.empty())
		return FALSE;

	// TODO : is it better with the BOM or without (just change the last argument)
	int nFileChanged = 0;
	BOOL bSuccess = OlecharToUTF8(filepath.c_str(), tempFilepath.c_str(), nFileChanged, FALSE); 
	if (!bSuccess)
		return FALSE;

	if (nFileChanged)
	{
		// we do not overwrite so we delete the old file
		if (bMayOverwrite)
		{
			if (!::DeleteFile(filepath.c_str()))
			{
				LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
					filepath.c_str(), GetSysError(GetLastError()).c_str()));
			}
		}
		// and change the filepath if everything works
		filepath = tempFilepath;
	}
	else
	{
		if (!::DeleteFile(tempFilepath.c_str()))
		{
			LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
				tempFilepath.c_str(), GetSysError(GetLastError()).c_str()));
		}
	}

	return TRUE;
}
BOOL FileTransform_NormalizeUnicode(String & filepath, BOOL bMayOverwrite)
{
	String tempDir = env_GetTempPath();
	if (tempDir.empty())
		return FALSE;
	String tempFilepath = env_GetTempFileName(tempDir.c_str(), _T("_WM"));
	if (tempFilepath.empty())
		return FALSE;

	int nFileChanged = 0;
	BOOL bSuccess = UnicodeFileToOlechar(filepath.c_str(), tempFilepath.c_str(), nFileChanged); 
	if (!bSuccess)
		return FALSE;

	if (nFileChanged)
	{
		// we do not overwrite so we delete the old file
		if (bMayOverwrite)
		{
			if (!::DeleteFile(filepath.c_str()))
			{
				LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
					filepath.c_str(), GetSysError(GetLastError()).c_str()));
			}
		}
		// and change the filepath if everything works
		filepath = tempFilepath;
	}
	else
	{
		if (!::DeleteFile(tempFilepath.c_str()))
		{
			LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
				tempFilepath.c_str(), GetSysError(GetLastError()).c_str()));
		}
	}


	return TRUE;
}
Exemple #6
0
/**
 * @brief Open file as memory-mapped file.
 * @param [in,out] fileData Memory-mapped file's info.
 * @return TRUE if opening succeeded, FALSE otherwise.
 */
BOOL files_openFileMapped(MAPPEDFILEDATA *fileData)
{
	DWORD dwProtectFlag = 0;
	DWORD dwMapAccess = 0;
	DWORD dwOpenAccess = 0;
	DWORD dwFileSizeHigh = 0;
	DWORD dwSharedMode = FILE_SHARE_READ;
	HANDLE hTemplateFile = NULL; // for creating new file
	BOOL bSuccess = TRUE;

	if (fileData->bWritable)
	{
		dwProtectFlag = PAGE_READWRITE;
		dwMapAccess = FILE_MAP_ALL_ACCESS;
		dwOpenAccess = GENERIC_READ | GENERIC_WRITE;
	}
	else
	{
		dwProtectFlag = PAGE_READONLY;
		dwMapAccess = FILE_MAP_READ;
		dwOpenAccess = GENERIC_READ;
	}

	fileData->hFile = CreateFile(fileData->fileName,
		dwOpenAccess, dwSharedMode, NULL, fileData->dwOpenFlags,
		FILE_ATTRIBUTE_NORMAL, hTemplateFile);

	if (fileData->hFile == INVALID_HANDLE_VALUE)
	{
		bSuccess = FALSE;
		LogErrorString(Fmt(_T("CreateFile(%s) failed in files_openFileMapped: %s")
			, fileData->fileName, GetSysError(GetLastError()).c_str()));
	}
	else
	{
		if (fileData->dwSize == 0)
		{
			fileData->dwSize = GetFileSize(fileData->hFile,
				 &dwFileSizeHigh);
			if (fileData->dwSize == 0xFFFFFFFF || dwFileSizeHigh)
			{
				fileData->dwSize = 0;
				bSuccess = FALSE;
			}
		}
	}
		
	if (bSuccess)
	{
		if (fileData->dwSize == 0 && dwFileSizeHigh == 0)
			// Empty file (but should be accepted anyway)
			return bSuccess;

		fileData->hMapping = CreateFileMapping(fileData->hFile,
				NULL, dwProtectFlag, 0, fileData->dwSize, NULL);
		if (!fileData->hMapping)
		{
			bSuccess = FALSE;
			LogErrorString(Fmt(_T("CreateFileMapping(%s) failed: %s")
				, fileData->fileName, GetSysError(GetLastError()).c_str()));
		}
		else
		{
			fileData->pMapBase = MapViewOfFile(fileData->hMapping,
				dwMapAccess, 0, 0, 0);
			if (!fileData->pMapBase)
			{
				bSuccess = FALSE;
				LogErrorString(Fmt(_T("MapViewOfFile(%s) failed: %s")
					, fileData->fileName, GetSysError(GetLastError()).c_str()));
			}
		}
	}

	if (!bSuccess)
	{
		UnmapViewOfFile(fileData->pMapBase);
		fileData->pMapBase = NULL;
		CloseHandle(fileData->hMapping);
		fileData->hMapping = NULL;
		CloseHandle(fileData->hFile);
		fileData->hFile = NULL;
	}
	return bSuccess;
}
Exemple #7
0
/*! \brief Start the worker thread

 This function start the worker thread.

 \param Pdx
   Pointer to a DEVICE_EXTENSION structure. 

 \return 
   If the routine succeeds, it returns STATUS_SUCCESS. 
   Otherwise, it return one of the error status values.
*/
NTSTATUS
cbm_start_thread(IN PDEVICE_EXTENSION Pdx)
{
    NTSTATUS ntStatus;
    PDEVICE_OBJECT fdo;

    FUNC_ENTER();

    DBG_ASSERT(Pdx != NULL);

    // get the FDO out of the PDX

    fdo = Pdx->Fdo;

    DBG_ASSERT(fdo != NULL);

    // The ThreadHandle as well as the thread object pointer should be
    // 0. If not, it means that the thread has already been started.

    DBG_ASSERT(Pdx->ThreadHandle == 0);
    DBG_ASSERT(Pdx->Thread == 0);

    PERF_EVENT_THREAD_START_SCHED();

    // The thread should not be quit yet.
    //! \todo Replace Pdx->QuitThread with a event for quitting

    Pdx->QuitThread = FALSE;

    // Create the thread that will execute our IRPs

    DBG_IRQL( == PASSIVE_LEVEL);
    ntStatus = PsCreateSystemThread(&Pdx->ThreadHandle,
        THREAD_ALL_ACCESS, // Desired access
        NULL,              // No object attributes
        NULL,              // which process should the thread belong to?
        NULL,              // Client ID
        cbm_thread,        // the routine to be started
        Pdx);              // context value for the thread

    if (!NT_SUCCESS(ntStatus))
    {
        // The thread could not been started, make sure this is logged

        DBG_ERROR((DBG_PREFIX "Creation of system thread FAILED, deleting device"));
        LogErrorString(fdo, CBM_START_FAILED, L"creation of the system thread.", NULL);
    }
    else
    {
        // Find out the thread object pointer, which is needed
        // for setting the thread priority. Furthermore, as we have
        // referenced the object, the driver will refuse to be unloaded
        // until the object is dereferenced.

        DBG_IRQL( == PASSIVE_LEVEL);
        ObReferenceObjectByHandle(Pdx->ThreadHandle,
            THREAD_ALL_ACCESS, NULL, KernelMode, &Pdx->Thread, NULL);

        DBG_ASSERT(Pdx->Thread);

        if (Pdx->Thread)
        {
            // Set the priority of the thread to a realtime priority.

            DBG_IRQL( == PASSIVE_LEVEL);
            KeSetPriorityThread(Pdx->Thread, LOW_REALTIME_PRIORITY);
        }
    }
Exemple #8
0
static HRESULT SendRequest(
    __in BURN_USER_EXPERIENCE* pUX,
    __in_z LPCWSTR wzPackageOrContainerId,
    __in_z LPCWSTR wzPayloadId,
    __in HINTERNET hUrl,
    __inout_z LPWSTR* psczUrl,
    __out BOOL* pfRetry,
    __out BOOL* pfRangesAccepted
    )
{
    HRESULT hr = S_OK;
    BOOL fRetrySend = FALSE;
    LONG lCode = 0;

    do
    {
        fRetrySend = FALSE;

        if (!::HttpSendRequestW(hUrl, NULL, 0, NULL, 0))
        {
            hr = HRESULT_FROM_WIN32(::GetLastError()); // remember the error that occurred and log it.
            LogErrorString(hr, "Failed to send request to URL: %ls, trying to process HTTP status code anyway.", *psczUrl);

            // Try to get the HTTP status code and, if good, handle via the switch statement below but if it
            // fails return the error code from the send request above as the result of the function.
            HRESULT hrQueryStatusCode = InternetQueryInfoNumber(hUrl, HTTP_QUERY_STATUS_CODE, &lCode);
            ExitOnFailure1(hrQueryStatusCode, "Failed to get HTTP status code for failed request to URL: %ls", *psczUrl);
        }
        else // get the http status code.
        {
            hr = InternetQueryInfoNumber(hUrl, HTTP_QUERY_STATUS_CODE, &lCode);
            ExitOnFailure1(hr, "Failed to get HTTP status code for request to URL: %ls", *psczUrl);
        }

        switch (lCode)
        {
        case 200: // OK but range requests don't work.
            *pfRangesAccepted = FALSE;
            hr = S_OK;
            break;

        case 206: // Partial content means that range requests work!
            *pfRangesAccepted = TRUE;
            hr = S_OK;
            break;

        // redirection cases
        case 301: __fallthrough; // file moved
        case 302: __fallthrough; // temporary
        case 303: // redirect method
            hr = InternetQueryInfoString(hUrl, HTTP_QUERY_CONTENT_LOCATION, psczUrl);
            ExitOnFailure1(hr, "Failed to get redirect url: %ls", *psczUrl);

            *pfRetry = TRUE;
            break;

        // error cases
        case 400: // bad request
            hr = HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME);
            break;

        case 401: __fallthrough; // unauthorized
        case 407: __fallthrough; // proxy unauthorized
            hr = AuthenticationRequired(pUX, wzPackageOrContainerId, wzPayloadId, hUrl, lCode, &fRetrySend, pfRetry);
            break;

        case 403: // forbidden
            hr = HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
            break;

        case 404: // file not found
        case 410: // gone
            hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
            break;

        case 405: // method not allowed
            hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
            break;

        case 408: __fallthrough; // request timedout
        case 504: // gateway timeout
            hr = HRESULT_FROM_WIN32(WAIT_TIMEOUT);
            break;

        case 414: // request URI too long
            hr = CO_E_PATHTOOLONG;
            break;

        case 502: __fallthrough; // server (through a gateway) was not found
        case 503: // server unavailable
            hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
            break;

        case 418: // I'm a teapot.
        default:
            // If the request failed and the HTTP status code was invalid (but wininet gave us a number anyway)
            // do not overwrite the error code from the failed request. Otherwise, the error was unexpected.
            if (SUCCEEDED(hr))
            {
                hr = E_UNEXPECTED;
            }

            LogErrorString(hr, "Unknown HTTP status code %d, returned from URL: %ls", lCode, *psczUrl);
            break;
        }
    } while (fRetrySend);

LExit:
    return hr;
}
Exemple #9
0
/**
 * @brief Runs diff-engine.
 */
BOOL CDiffWrapper::RunFileDiff()
{
	String filepath1(m_s1File);
	String filepath2(m_s2File);
	replace_char(&*filepath1.begin(), '/', '\\');
	replace_char(&*filepath2.begin(), '/', '\\');

	BOOL bRet = TRUE;
	String strFile1Temp(filepath1);
	String strFile2Temp(filepath2);
	
	m_options.SetToDiffUtils();

	if (m_bUseDiffList)
		m_nDiffs = m_pDiffList->GetSize();

	if (m_bPluginsEnabled)
	{
		// Do the preprocessing now, overwrite the temp files
		// NOTE: FileTransform_UCS2ToUTF8() may create new temp
		// files and return new names, those created temp files
		// are deleted in end of function.
		if (m_infoPrediffer->bToBeScanned)
		{
			// this can only fail if the data can not be saved back (no more
			// place on disk ???) What to do then ??
			FileTransform_Prediffing(strFile1Temp, m_sToFindPrediffer.c_str(), m_infoPrediffer,
				m_bPathsAreTemp);
		}
		else
		{
			// This can fail if the prediffer has a problem
			if (FileTransform_Prediffing(strFile1Temp, *m_infoPrediffer,
				m_bPathsAreTemp) == FALSE)
			{
				// display a message box
				CString sError;
				LangFormatString2(sError, IDS_PREDIFFER_ERROR, strFile1Temp.c_str(),
					m_infoPrediffer->pluginName.c_str());
				AfxMessageBox(sError, MB_OK | MB_ICONSTOP);
				// don't use any more this prediffer
				m_infoPrediffer->bToBeScanned = FALSE;
				m_infoPrediffer->pluginName.erase();
			}
		}

		// We use the same plugin for both files, so it must be defined before
		// second file
		ASSERT(m_infoPrediffer->bToBeScanned == FALSE);
		if (FileTransform_Prediffing(strFile2Temp, *m_infoPrediffer,
			m_bPathsAreTemp) == FALSE)
		{
			// display a message box
			CString sError;
			LangFormatString2(sError, IDS_PREDIFFER_ERROR, strFile2Temp.c_str(),
				m_infoPrediffer->pluginName.c_str());
			AfxMessageBox(sError, MB_OK | MB_ICONSTOP);
			// don't use any more this prediffer
			m_infoPrediffer->bToBeScanned = FALSE;
			m_infoPrediffer->pluginName.erase();
		}
	}

	// Comparing UTF-8 files seems to require this conversion?
	// I'm still very confused about why, as what the functions
	// document doing is UCS2 to UTF-8 conversion, nothing else.
	// Something is wrong here. - Kimmo
	FileTransform_UCS2ToUTF8(strFile1Temp, m_bPathsAreTemp);
	FileTransform_UCS2ToUTF8(strFile2Temp, m_bPathsAreTemp);

	DiffFileData diffdata;
	diffdata.SetDisplayFilepaths(filepath1.c_str(), filepath2.c_str()); // store true names for diff utils patch file
	// This opens & fstats both files (if it succeeds)
	if (!diffdata.OpenFiles(strFile1Temp.c_str(), strFile2Temp.c_str()))
	{
		return FALSE;
	}

	// Compare the files, if no error was found.
	// Last param (bin_file) is NULL since we don't
	// (yet) need info about binary sides.
	int bin_flag = 0;
	struct change *script = NULL;
	bRet = Diff2Files(&script, &diffdata, &bin_flag, NULL);

	// We don't anymore create diff-files for every rescan.
	// User can create patch-file whenever one wants to.
	// We don't need to waste time. But lets keep this as
	// debugging aid. Sometimes it is very useful to see
	// what differences diff-engine sees!
#ifdef _DEBUG
	// throw the diff into a temp file
	String sTempPath = env_GetTempPath(); // get path to Temp folder
	String path = paths_ConcatPath(sTempPath, _T("Diff.txt"));

	outfile = _tfopen(path.c_str(), _T("w+"));
	if (outfile != NULL)
	{
		print_normal_script(script);
		fclose(outfile);
		outfile = NULL;
	}
#endif

	// First determine what happened during comparison
	// If there were errors or files were binaries, don't bother
	// creating diff-lists or patches
	
	// diff_2_files set bin_flag to -1 if different binary
	// diff_2_files set bin_flag to +1 if same binary
	if (bin_flag != 0)
	{
		m_status.bBinaries = TRUE;
		if (bin_flag == -1)
			m_status.bIdentical = FALSE;
		else
			m_status.bIdentical = TRUE;
	}
	else
	{ // text files according to diffutils, so change script exists
		m_status.bIdentical = (script == 0);
		m_status.bBinaries = FALSE;
	}
	file_data * inf = diffdata.m_inf;
	m_status.bLeftMissingNL = inf[0].missing_newline;
	m_status.bRightMissingNL = inf[1].missing_newline;


	// Create patch file
	if (!m_status.bBinaries && m_bCreatePatchFile)
	{
		WritePatchFile(script, &inf[0]);
	}
	
	// Go through diffs adding them to WinMerge's diff list
	// This is done on every WinMerge's doc rescan!
	if (!m_status.bBinaries && m_bUseDiffList)
	{
		LoadWinMergeDiffsFromDiffUtilsScript(script, diffdata.m_inf);
	}			

	FreeDiffUtilsScript(script);

	// Done with diffutils filedata
	diffdata.Close();

	if (m_bPluginsEnabled)
	{
		// Delete temp files transformation functions possibly created
		if (lstrcmpi(filepath1.c_str(), strFile1Temp.c_str()) != 0)
		{
			if (!::DeleteFile(strFile1Temp.c_str()))
			{
				LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
					strFile1Temp.c_str(), GetSysError(GetLastError()).c_str()));
			}
			strFile1Temp.erase();
		}
		if (lstrcmpi(filepath2.c_str(), strFile2Temp.c_str()) != 0)
		{
			if (!::DeleteFile(strFile2Temp.c_str()))
			{
				LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
					strFile2Temp.c_str(), GetSysError(GetLastError()).c_str()));
			}
			strFile2Temp.erase();
		}
	}
	return bRet;
}
Exemple #10
0
static HRESULT DeleteEmptyDirectory(
    __in LEGACY_FILE_TYPE fileType,
    __in_z LPCWSTR wzPath
    )
{
    HRESULT hr = S_OK;

    LPWSTR sczParentDirectory = NULL;
    DWORD dwIndex = 0;
    LPWSTR pwcLastBackslash = NULL;

    // If it's an individual file and it exists, no point trying to delete any directories for it
    if (LEGACY_FILE_PLAIN == fileType)
    {
        if (FileExistsEx(wzPath, NULL))
        {
            ExitFunction1(hr = S_OK);
        }
    }
    else
    {
        // It's a directory, so delete children first
        hr = DeleteEmptyDirectoryChildren(wzPath);
        // This code is just an FYI that the directory was not empty and so wasn't deleted. It's not an error, so ignore it.
        if (FAILED(hr))
        {
            ExitFunction1(hr = S_OK);
        }
        ExitOnFailure(hr, "Failed to check for empty directories and delete them at path: %ls", wzPath);
    }

    hr = StrAllocString(&sczParentDirectory, wzPath, 0);
    ExitOnFailure(hr, "Failed to allocate copy of directory");

    // Eliminate any trailing backslashes from the directory first, if there are any
    dwIndex = lstrlenW(sczParentDirectory);
    if (0 == dwIndex)
    {
        hr = E_INVALIDARG;
        ExitOnFailure(hr, "Unexpected empty parent directory encountered while deleting empty directories");
    }

    --dwIndex; // Start at the last character of the string
    while (dwIndex > 0 && sczParentDirectory[dwIndex] == L'\\')
    {
        sczParentDirectory[dwIndex] = L'\0';
        --dwIndex;
    }

    if (0 == dwIndex)
    {
        hr = E_INVALIDARG;
        ExitOnFailure(hr, "Parent directory was entirely composed of backslashes!");
    }

    // Now delete any empty parent directories we see as well
    while (NULL != (pwcLastBackslash = wcsrchr(sczParentDirectory, L'\\')))
    {
        hr = DirEnsureDelete(sczParentDirectory, FALSE, FALSE);
        if (FAILED(hr))
        {
            LogErrorString(hr, "Failed to check for empty parent directories and delete them at directory: %ls", sczParentDirectory);
            hr = S_OK;
            break;
        }

        *pwcLastBackslash = L'\0';
    }

LExit:
    ReleaseStr(sczParentDirectory);

    return hr;
}
Exemple #11
0
static HRESULT DeleteEmptyRegistryKeys(
    __in LEGACY_SYNC_PRODUCT_SESSION *pSyncProductSession
    )
{
    HRESULT hr = S_OK;
    const LEGACY_REGISTRY_KEY *rgRegKeys = pSyncProductSession->product.rgRegKeys;
    const DWORD cRegKeys = pSyncProductSession->product.cRegKeys;
    DWORD dwIndex = 0;
    LPWSTR pwcLastBackslash = NULL;
    LPWSTR sczParentKey = NULL;

    for (DWORD i = 0; i < cRegKeys; ++i)
    {
        hr = DeleteEmptyRegistryKeyChildren(rgRegKeys[i].dwRoot, rgRegKeys[i].sczKey);
        // This code is just an FYI that the key was not empty and so wasn't deleted. It's not an error, so ignore it.
        if (HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY) == hr)
        {
            hr = S_OK;
            continue;
        }
        ExitOnFailure(hr, "Failed to check for empty keys and delete them at root: %u, subkey: %ls", rgRegKeys[i].dwRoot, rgRegKeys[i].sczKey);

        hr = StrAllocString(&sczParentKey, rgRegKeys[i].sczKey, 0);
        ExitOnFailure(hr, "Failed to allocate copy of subkey");

        // Eliminate any trailing backslashes from the key first, if there are any
        dwIndex = lstrlenW(sczParentKey);
        if (0 == dwIndex)
        {
            hr = E_INVALIDARG;
            ExitOnFailure(hr, "Unexpected empty parent key encountered while deleting empty registry keys");
        }

        --dwIndex; // Start at the last character of the string
        while (dwIndex > 0 && sczParentKey[dwIndex] == L'\\')
        {
            sczParentKey[dwIndex] = L'\0';
            --dwIndex;
        }

        if (0 == dwIndex)
        {
            hr = E_INVALIDARG;
            ExitOnFailure(hr, "Parent key was entirely composed of backslashes!");
        }

        // Now delete any empty parent keys we see as well
        while (NULL != (pwcLastBackslash = wcsrchr(sczParentKey, L'\\')))
        {
            hr = RegDelete(ManifestConvertToRootKey(rgRegKeys[i].dwRoot), sczParentKey, REG_KEY_DEFAULT, FALSE);
            // This code is just an FYI that the key was not empty and so wasn't deleted. It's not an error, so ignore it.
            if (FAILED(hr))
            {
                LogErrorString(hr, "Failed to check for empty parent keys and delete them at root: %u, subkey: %ls", rgRegKeys[i].dwRoot, sczParentKey);
                hr = S_OK;
                break;
            }

            *pwcLastBackslash = L'\0';
        }
    }

LExit:
    ReleaseStr(sczParentKey);

    return hr;
}
void COpenView::OnInitialUpdate()
{
	m_sizeOrig = GetTotalSize();

	theApp.TranslateDialog(m_hWnd);

	if (!m_picture.Load(IDR_LOGO))
		return;

	CFormView::OnInitialUpdate();
	ResizeParentToFit();

	// set caption to "swap paths" button
	LOGFONT lf;
	GetDlgItem(IDC_SWAP01_BUTTON)->GetFont()->GetObject(sizeof(lf), &lf);
	lf.lfCharSet = SYMBOL_CHARSET;
	lstrcpy(lf.lfFaceName, _T("Wingdings"));
	m_fontSwapButton.CreateFontIndirect(&lf);
	const int ids[] = {IDC_SWAP01_BUTTON, IDC_SWAP12_BUTTON, IDC_SWAP02_BUTTON};
	for (int i = 0; i < sizeof(ids)/sizeof(ids[0]); ++i)
	{
		GetDlgItem(ids[i])->SetFont(&m_fontSwapButton);
		SetDlgItemText(ids[i], _T("\xf4"));
	}

	m_constraint.InitializeCurrentSize(this);
	m_constraint.InitializeSpecificSize(this, m_sizeOrig.cx, m_sizeOrig.cy);
	m_constraint.SetMaxSizePixels(-1, m_sizeOrig.cy);
	m_constraint.SetScrollScale(this, 1.0, 1.0);
	m_constraint.SetSizeGrip(prdlg::CMoveConstraint::SG_NONE);
	// configure how individual controls adjust when dialog resizes
	m_constraint.ConstrainItem(IDC_PATH0_COMBO, 0, 1, 0, 0); // grows right
	m_constraint.ConstrainItem(IDC_PATH1_COMBO, 0, 1, 0, 0); // grows right
	m_constraint.ConstrainItem(IDC_PATH2_COMBO, 0, 1, 0, 0); // grows right
	m_constraint.ConstrainItem(IDC_EXT_COMBO, 0, 1, 0, 0); // grows right
	m_constraint.ConstrainItem(IDC_UNPACKER_EDIT, 0, 1, 0, 0); // grows right
	m_constraint.ConstrainItem(IDC_FILES_DIRS_GROUP, 0, 1, 0, 0); // grows right
	m_constraint.ConstrainItem(IDC_PATH0_BUTTON, 1, 0, 0, 0); // slides right
	m_constraint.ConstrainItem(IDC_PATH1_BUTTON, 1, 0, 0, 0); // slides right
	m_constraint.ConstrainItem(IDC_PATH2_BUTTON, 1, 0, 0, 0); // slides right
	m_constraint.ConstrainItem(IDC_PATH0_READONLY, 1, 0, 0, 0); // slides right
	m_constraint.ConstrainItem(IDC_PATH1_READONLY, 1, 0, 0, 0); // slides right
	m_constraint.ConstrainItem(IDC_PATH2_READONLY, 1, 0, 0, 0); // slides right
	m_constraint.ConstrainItem(IDC_SWAP01_BUTTON, 1, 0, 0, 0); // slides right
	m_constraint.ConstrainItem(IDC_SWAP12_BUTTON, 1, 0, 0, 0); // slides right
	m_constraint.ConstrainItem(IDC_SWAP02_BUTTON, 1, 0, 0, 0); // slides right
	m_constraint.ConstrainItem(IDC_SELECT_UNPACKER, 1, 0, 0, 0); // slides right
	m_constraint.ConstrainItem(IDC_OPEN_STATUS, 0, 1, 0, 0); // grows right
	m_constraint.ConstrainItem(IDC_SELECT_FILTER, 1, 0, 0, 0); // slides right
	m_constraint.ConstrainItem(IDOK, 1, 0, 0, 0); // slides right
	m_constraint.ConstrainItem(IDCANCEL, 1, 0, 0, 0); // slides right
	m_constraint.ConstrainItem(ID_HELP, 1, 0, 0, 0); // slides right
	m_constraint.DisallowHeightGrowth();
	//m_constraint.SubclassWnd(); // install subclassing

	m_constraint.LoadPosition(_T("ResizeableDialogs"), _T("OpenView"), false); // persist size via registry
	m_constraint.UpdateSizes();

	COpenDoc *pDoc = GetDocument();

	CString strTitle;
	GetWindowText(strTitle);
	pDoc->SetTitle(strTitle);

	m_files = pDoc->m_files;
	m_bRecurse = pDoc->m_bRecurse;
	m_strExt = pDoc->m_strExt;
	m_strUnpacker = pDoc->m_strUnpacker;
	m_infoHandler = pDoc->m_infoHandler;
	m_dwFlags[0] = pDoc->m_dwFlags[0];
	m_dwFlags[1] = pDoc->m_dwFlags[1];
	m_dwFlags[2] = pDoc->m_dwFlags[2];

	for (int file = 0; file < m_files.GetSize(); file++)
	{
		m_strPath[file] = m_files[file];
		m_ctlPath[file].SetWindowText(m_files[file].c_str());
		m_bReadOnly[file] = (m_dwFlags[file] & FFILEOPEN_READONLY) != 0;
	}

	m_ctlPath[0].AttachSystemImageList();
	m_ctlPath[1].AttachSystemImageList();
	m_ctlPath[2].AttachSystemImageList();
	LoadComboboxStates();

	BOOL bDoUpdateData = TRUE;
	for (int index = 0; index < countof(m_strPath); index++)
	{
		if (!m_strPath[index].empty())
			bDoUpdateData = FALSE;
	}
	UpdateData(bDoUpdateData);

	String filterNameOrMask = theApp.m_pGlobalFileFilter->GetFilterNameOrMask();
	BOOL bMask = theApp.m_pGlobalFileFilter->IsUsingMask();

	if (!bMask)
	{
		String filterPrefix = _("[F] ");
		filterNameOrMask = filterPrefix + filterNameOrMask;
	}

	int ind = m_ctlExt.FindStringExact(0, filterNameOrMask.c_str());
	if (ind != CB_ERR)
		m_ctlExt.SetCurSel(ind);
	else
	{
		ind = m_ctlExt.InsertString(0, filterNameOrMask.c_str());
		if (ind != CB_ERR)
			m_ctlExt.SetCurSel(ind);
		else
			LogErrorString(_T("Failed to add string to filters combo list!"));
	}

	if (!GetOptionsMgr()->GetBool(OPT_VERIFY_OPEN_PATHS))
	{
		EnableDlgItem(IDOK, true);
		EnableDlgItem(IDC_UNPACKER_EDIT, true);
		EnableDlgItem(IDC_SELECT_UNPACKER, true);
	}

	UpdateButtonStates();

	BOOL bOverwriteRecursive = FALSE;
	if (m_dwFlags[0] & FFILEOPEN_PROJECT || m_dwFlags[1] & FFILEOPEN_PROJECT)
		bOverwriteRecursive = TRUE;
	if (m_dwFlags[0] & FFILEOPEN_CMDLINE || m_dwFlags[1] & FFILEOPEN_CMDLINE)
		bOverwriteRecursive = TRUE;
	if (!bOverwriteRecursive)
		m_bRecurse = GetOptionsMgr()->GetBool(OPT_CMP_INCLUDE_SUBDIRS);

	m_strUnpacker = m_infoHandler.pluginName;
	UpdateData(FALSE);
	SetStatus(IDS_OPEN_FILESDIRS);
	SetUnpackerStatus(IDS_OPEN_UNPACKERDISABLED);

	m_pDropHandler = new DropHandler(std::bind(&COpenView::OnDropFiles, this, std::placeholders::_1));
	RegisterDragDrop(m_hWnd, m_pDropHandler);
}