Пример #1
0
/*******************************************************************
 LoadSystemLibraryWithPath - Fully qualifies the path to a module in
                             the Windows system directory and loads it
                             and returns the path

 Returns
   E_MODNOTFOUND - The module could not be found.
   * - Another error occured.
********************************************************************/
extern "C" HRESULT DAPI LoadSystemLibraryWithPath(
    __in_z LPCWSTR wzModuleName,
    __out HMODULE *phModule,
    __deref_out_z_opt LPWSTR* psczPath
    )
{
    HRESULT hr = S_OK;
    DWORD cch = 0;
    WCHAR wzPath[MAX_PATH] = { };

    cch = ::GetSystemDirectoryW(wzPath, MAX_PATH);
    ExitOnNullWithLastError(cch, hr, "Failed to get the Windows system directory.");

    if (L'\\' != wzPath[cch - 1])
    {
        hr = ::StringCchCatNW(wzPath, MAX_PATH, L"\\", 1);
        ExitOnRootFailure(hr, "Failed to terminate the string with a backslash.");
    }

    hr = ::StringCchCatW(wzPath, MAX_PATH, wzModuleName);
    ExitOnRootFailure1(hr, "Failed to create the fully-qualified path to %ls.", wzModuleName);

    *phModule = ::LoadLibraryW(wzPath);
    ExitOnNullWithLastError1(*phModule, hr, "Failed to load the library %ls.", wzModuleName);

    if (psczPath)
    {
        hr = StrAllocString(psczPath, wzPath, MAX_PATH);
        ExitOnFailure(hr, "Failed to copy the path to library.");
    }

LExit:
    return hr;
}
Пример #2
0
static HRESULT GetUpdateMutex(
    __in LPCWSTR wzAppId,
    __out HANDLE *phMutex
    )
{
    HRESULT hr = S_OK;
    HANDLE h = INVALID_HANDLE_VALUE;
    WCHAR wzMutexName[MAX_PATH];

    hr = ::StringCchPrintfW(wzMutexName, countof(wzMutexName), L"Local\\CT_UPDATE_%S",wzAppId);
    ExitOnFailure(hr, "Failed to StringCchPrintfW the Update mutex's name.");

    h = ::CreateMutexW(NULL, FALSE, wzMutexName);
    ExitOnNullWithLastError1(h, hr, "Failed to open mutex %S", wzMutexName);

    if (WAIT_OBJECT_0 == ::WaitForSingleObject(h, 0))
    {
        *phMutex = h;
    }
    else
    {
        ::CloseHandle(h);
        *phMutex = INVALID_HANDLE_VALUE;
    }

LExit:
    return hr;
}
Пример #3
0
HRESULT GetUpdateMutex(
    __in const GUID *pGuid,
    __out HANDLE *phMutex
    )
{
    HRESULT hr = S_OK;
    HANDLE h = INVALID_HANDLE_VALUE;
    WCHAR wzMutexName[MAX_PATH];

    hr = ::StringCchPrintfW(
        wzMutexName, 
        countof(wzMutexName), 
        L"Local\\CT_UPDATE_%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
        pGuid->Data1, 
        pGuid->Data2, 
        pGuid->Data3, 
        pGuid->Data4[0], 
        pGuid->Data4[1], 
        pGuid->Data4[2], 
        pGuid->Data4[3], 
        pGuid->Data4[4], 
        pGuid->Data4[5], 
        pGuid->Data4[6], 
        pGuid->Data4[7]
    );
    ExitOnFailure(hr, "Failed to StringCchPrintfW the Update mutex's name.");

    h = ::CreateMutexW(NULL, FALSE, wzMutexName);
    ExitOnNullWithLastError1(h, hr, "Failed to open mutex %S", wzMutexName);

    if (WAIT_OBJECT_0 == ::WaitForSingleObject(h, 0))
    {
        *phMutex = h;
    }
    else
    {
        ::CloseHandle(h);
        *phMutex = INVALID_HANDLE_VALUE;
    }

LExit:
    return hr;
}
Пример #4
0
/********************************************************************
RmuAddProcessById - Adds the process ID to the Restart Manager sesion.

You should call this multiple times as necessary before calling
RmuRegisterResources.

********************************************************************/
extern "C" HRESULT DAPI RmuAddProcessById(
    __in PRMU_SESSION pSession,
    __in DWORD dwProcessId
    )
{
    HRESULT hr = S_OK;
    HANDLE hProcess = NULL;
    FILETIME CreationTime = {};
    FILETIME ExitTime = {};
    FILETIME KernelTime = {};
    FILETIME UserTime = {};
    BOOL fLocked = FALSE;

    hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
    ExitOnNullWithLastError1(hProcess, hr, "Failed to open the process ID %d.", dwProcessId);

    if (!::GetProcessTimes(hProcess, &CreationTime, &ExitTime, &KernelTime, &UserTime))
    {
        ExitWithLastError1(hr, "Failed to get the process times for process ID %d.", dwProcessId);
    }

    ::EnterCriticalSection(&pSession->cs);
    fLocked = TRUE;

    hr = RmuApplicationArrayAlloc(&pSession->rgApplications, &pSession->cApplications, dwProcessId, CreationTime);
    ExitOnFailure(hr, "Failed to add the application to the array.");

LExit:
    if (hProcess)
    {
        ::CloseHandle(hProcess);
    }

    if (fLocked)
    {
        ::LeaveCriticalSection(&pSession->cs);
    }

    return hr;
}
Пример #5
0
/********************************************************************
ResGetStringLangId - get the language id for a string in the string table.

********************************************************************/
extern "C" HRESULT DAPI ResGetStringLangId(
    __in_opt LPCWSTR wzPath,
    __in UINT uID,
    __out WORD *pwLangId
    )
{
    Assert(pwLangId);

    HRESULT hr = S_OK;
    HINSTANCE hModule = NULL;
    DWORD dwBlockId = (uID / RES_STRINGS_PER_BLOCK) + 1;
    WORD wFoundLangId = 0;

    if (wzPath && *wzPath)
    {
        hModule = LoadLibraryExW(wzPath, NULL, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
        ExitOnNullWithLastError1(hModule, hr, "Failed to open resource file: %ls", wzPath);
    }

#pragma prefast(push)
#pragma prefast(disable:25068)
    if (!::EnumResourceLanguagesA(hModule, RT_STRING, MAKEINTRESOURCE(dwBlockId), static_cast<ENUMRESLANGPROC>(EnumLangIdProc), reinterpret_cast<LONG_PTR>(&wFoundLangId)))
#pragma prefast(pop)
    {
        ExitWithLastError(hr, "Failed to find string language identifier.");
    }

    *pwLangId = wFoundLangId;

LExit:
    if (hModule)
    {
        ::FreeLibrary(hModule);
    }

    return hr;
}
Пример #6
0
static HRESULT CreateNetFxChainer(
    __in LPCWSTR wzSectionName,
    __in LPCWSTR wzEventName,
    __out NetFxChainer** ppChainer
)
{
    HRESULT hr = S_OK;
    LPWSTR sczName = NULL;
    NetFxChainer* pChainer = NULL;

    pChainer = (NetFxChainer*)MemAlloc(sizeof(NetFxChainer), TRUE);
    ExitOnNull(pChainer, hr, E_OUTOFMEMORY, "Failed to allocate memory for NetFxChainer struct.");

    pChainer->hEventChaineeSend = ::CreateEvent(NULL, FALSE, FALSE, wzEventName);
    ExitOnNullWithLastError1(pChainer->hEventChaineeSend, hr, "Failed to create event: %ls", wzEventName);

    hr = StrAllocFormatted(&sczName, L"%ls_send", wzEventName);
    ExitOnFailure(hr, "failed to allocate memory for event name");

    pChainer->hEventChainerSend = ::CreateEvent(NULL, FALSE, FALSE, sczName);
    ExitOnNullWithLastError1(pChainer->hEventChainerSend, hr, "Failed to create event: %ls", sczName);

    hr = StrAllocFormatted(&sczName, L"%ls_mutex", wzEventName);
    ExitOnFailure(hr, "failed to allocate memory for mutex name");

    // Create the mutex, we initially own
    pChainer->hMutex = ::CreateMutex(NULL, TRUE, sczName);
    ExitOnNullWithLastError1(pChainer->hMutex, hr, "Failed to create mutex: %ls", sczName);

    pChainer->hSection = ::CreateFileMapping(INVALID_HANDLE_VALUE,
                         NULL, // security attributes
                         PAGE_READWRITE,
                         0, // high-order DWORD of maximum size
                         NETFXDATA_SIZE, // low-order DWORD of maximum size
                         wzSectionName);
    ExitOnNullWithLastError1(pChainer->hSection, hr, "Failed to memory map cabinet file: %ls", wzSectionName);

    pChainer->pData = reinterpret_cast<NetFxDataStructure*>(::MapViewOfFile(pChainer->hSection,
                      FILE_MAP_WRITE,
                      0, 0, // offsets
                      0 // map entire file
                                                                           ));
    ExitOnNullWithLastError1(pChainer->pData, hr, "Failed to MapViewOfFile for %ls.", wzSectionName);

    // Initialize the shared memory
    hr = ::StringCchCopyW(pChainer->pData->szEventName, countof(pChainer->pData->szEventName), wzEventName);
    ExitOnFailure(hr, "failed to copy event name to shared memory structure.");
    pChainer->pData->downloadFinished = false;
    pChainer->pData->downloadSoFar = 0;
    pChainer->pData->hrDownloadFinished = E_PENDING;
    pChainer->pData->downloadAbort = false;
    pChainer->pData->installFinished = false;
    pChainer->pData->installSoFar = 0;
    pChainer->pData->hrInstallFinished = E_PENDING;
    pChainer->pData->installAbort = false;
    pChainer->pData->hrInternalError = S_OK;
    pChainer->pData->version = NETFXDATA_VERSION;
    pChainer->pData->messageCode = 0;
    pChainer->pData->messageResponse = 0;
    pChainer->pData->messageDataLength = 0;

    // Done with initialization, allow others to access.
    ::ReleaseMutex(pChainer->hMutex);

    *ppChainer = pChainer;
    pChainer = NULL;

LExit:
    ReleaseStr(sczName);

    if (pChainer)
    {
        // Something failed, release the mutex and destroy the object
        if (pChainer->hMutex)
        {
            ::ReleaseMutex(pChainer->hMutex);
        }

        DestroyNetFxChainer(pChainer);
    }

    return  hr;
}
Пример #7
0
/*******************************************************************
 PipeChildConnect - Called from the child process to connect back
                    to the pipe provided by the parent process.

*******************************************************************/
extern "C" HRESULT PipeChildConnect(
    __in BURN_PIPE_CONNECTION* pConnection,
    __in BOOL fConnectCachePipe
    )
{
    Assert(pConnection->sczName);
    Assert(pConnection->sczSecret);
    Assert(!pConnection->hProcess);
    Assert(INVALID_HANDLE_VALUE == pConnection->hPipe);
    Assert(INVALID_HANDLE_VALUE == pConnection->hCachePipe);

    HRESULT hr = S_OK;
    LPWSTR sczPipeName = NULL;

    // Try to connect to the parent.
    hr = StrAllocFormatted(&sczPipeName, PIPE_NAME_FORMAT_STRING, pConnection->sczName);
    ExitOnFailure(hr, "Failed to allocate name of parent pipe.");

    hr = E_UNEXPECTED;
    for (DWORD cRetry = 0; FAILED(hr) && cRetry < PIPE_RETRY_FOR_CONNECTION; ++cRetry)
    {
        pConnection->hPipe = ::CreateFileW(sczPipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
        if (INVALID_HANDLE_VALUE == pConnection->hPipe)
        {
            hr = HRESULT_FROM_WIN32(::GetLastError());
            if (E_FILENOTFOUND == hr) // if the pipe isn't created, call it a timeout waiting on the parent.
            {
                hr = HRESULT_FROM_WIN32(ERROR_TIMEOUT);
            }

            ::Sleep(PIPE_WAIT_FOR_CONNECTION);
        }
        else // we have a connection, go with it.
        {
            hr = S_OK;
        }
    }
    ExitOnRootFailure1(hr, "Failed to open parent pipe: %ls", sczPipeName)

    // Verify the parent and notify it that the child connected.
    hr = ChildPipeConnected(pConnection->hPipe, pConnection->sczSecret, &pConnection->dwProcessId);
    ExitOnFailure1(hr, "Failed to verify parent pipe: %ls", sczPipeName);

    if (fConnectCachePipe)
    {
        // Connect to the parent for the cache pipe.
        hr = StrAllocFormatted(&sczPipeName, CACHE_PIPE_NAME_FORMAT_STRING, pConnection->sczName);
        ExitOnFailure(hr, "Failed to allocate name of parent cache pipe.");

        pConnection->hCachePipe = ::CreateFileW(sczPipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
        if (INVALID_HANDLE_VALUE == pConnection->hCachePipe)
        {
            ExitWithLastError1(hr, "Failed to open parent pipe: %ls", sczPipeName)
        }

        // Verify the parent and notify it that the child connected.
        hr = ChildPipeConnected(pConnection->hCachePipe, pConnection->sczSecret, &pConnection->dwProcessId);
        ExitOnFailure1(hr, "Failed to verify parent pipe: %ls", sczPipeName);
    }

    pConnection->hProcess = ::OpenProcess(SYNCHRONIZE, FALSE, pConnection->dwProcessId);
    ExitOnNullWithLastError1(pConnection->hProcess, hr, "Failed to open companion process with PID: %u", pConnection->dwProcessId);

LExit:
    ReleaseStr(sczPipeName);

    return hr;
}
Пример #8
0
static HRESULT MakeRequest(
    __in BURN_USER_EXPERIENCE* pUX,
    __in_z LPCWSTR wzPackageOrContainerId,
    __in_z LPCWSTR wzPayloadId,
    __in HINTERNET hSession,
    __inout_z LPWSTR* psczSourceUrl,
    __in_z_opt LPCWSTR wzMethod,
    __in_z_opt LPCWSTR wzHeaders,
    __in_z_opt LPCWSTR wzUser,
    __in_z_opt LPCWSTR wzPassword,
    __out HINTERNET* phConnect,
    __out HINTERNET* phUrl,
    __out BOOL* pfRangeRequestsAccepted
    )
{
    HRESULT hr = S_OK;
    HINTERNET hConnect = NULL;
    HINTERNET hUrl = NULL;
    URI_INFO uri = { };

    // Try to open the URL.
    BOOL fRetry;
    do
    {
        fRetry = FALSE;

        // If the URL was opened close it, so we can reopen it again.
        ReleaseInternet(hUrl);
        ReleaseInternet(hConnect);

        // Open the url.
        hr = UriCrackEx(*psczSourceUrl, &uri);
        ExitOnFailure(hr, "Failed to break URL into server and resource parts.");

        hConnect = ::InternetConnectW(hSession, uri.sczHostName, uri.port, (wzUser && *wzUser) ? wzUser : uri.sczUser, (wzPassword && *wzPassword) ? wzPassword : uri.sczPassword, INTERNET_SCHEME_FTP == uri.scheme ? INTERNET_SERVICE_FTP : INTERNET_SERVICE_HTTP, 0, 0);
        ExitOnNullWithLastError1(hConnect, hr, "Failed to connect to URL: %ls", *psczSourceUrl);

        // Best effort set the proxy username and password, if they were provided.
        if ((wzUser && *wzUser) && (wzPassword && *wzPassword))
        {
            if (::InternetSetOptionW(hConnect, INTERNET_OPTION_PROXY_USERNAME, (LPVOID)wzUser, lstrlenW(wzUser)))
            {
                ::InternetSetOptionW(hConnect, INTERNET_OPTION_PROXY_PASSWORD, (LPVOID)wzPassword, lstrlenW(wzPassword));
            }
        }

        hr = OpenRequest(hConnect, wzMethod, uri.scheme, uri.sczPath, uri.sczQueryString, wzHeaders, &hUrl);
        ExitOnFailure1(hr, "Failed to open internet URL: %ls", *psczSourceUrl);

        hr = SendRequest(pUX, wzPackageOrContainerId, wzPayloadId, hUrl, psczSourceUrl, &fRetry, pfRangeRequestsAccepted);
        ExitOnFailure1(hr, "Failed to send request to URL: %ls", *psczSourceUrl);
    } while (fRetry);

    // Okay, we're all ready to start downloading. Update the connection information.
    *phConnect = hConnect;
    hConnect = NULL;
    *phUrl = hUrl;
    hUrl = NULL;

LExit:
    UriInfoUninitialize(&uri);
    ReleaseInternet(hUrl);
    ReleaseInternet(hConnect);

    return hr;
}