diff options
Diffstat (limited to 'src/engine/pipe.cpp')
| -rw-r--r-- | src/engine/pipe.cpp | 105 |
1 files changed, 28 insertions, 77 deletions
diff --git a/src/engine/pipe.cpp b/src/engine/pipe.cpp index 47963e9d..a9fd24e8 100644 --- a/src/engine/pipe.cpp +++ b/src/engine/pipe.cpp | |||
| @@ -429,7 +429,6 @@ extern "C" HRESULT PipeWaitForChildConnect( | |||
| 429 | DWORD cbSecret = lstrlenW(wzSecret) * sizeof(WCHAR); | 429 | DWORD cbSecret = lstrlenW(wzSecret) * sizeof(WCHAR); |
| 430 | DWORD dwCurrentProcessId = ::GetCurrentProcessId(); | 430 | DWORD dwCurrentProcessId = ::GetCurrentProcessId(); |
| 431 | DWORD dwAck = 0; | 431 | DWORD dwAck = 0; |
| 432 | DWORD cb = 0; | ||
| 433 | 432 | ||
| 434 | for (DWORD i = 0; i < countof(hPipes) && INVALID_HANDLE_VALUE != hPipes[i]; ++i) | 433 | for (DWORD i = 0; i < countof(hPipes) && INVALID_HANDLE_VALUE != hPipes[i]; ++i) |
| 435 | { | 434 | { |
| @@ -487,26 +486,18 @@ extern "C" HRESULT PipeWaitForChildConnect( | |||
| 487 | } | 486 | } |
| 488 | 487 | ||
| 489 | // Prove we are the one that created the elevated process by passing the secret. | 488 | // Prove we are the one that created the elevated process by passing the secret. |
| 490 | if (!::WriteFile(hPipe, &cbSecret, sizeof(cbSecret), &cb, NULL)) | 489 | hr = FileWriteHandle(hPipe, reinterpret_cast<LPCBYTE>(&cbSecret), sizeof(cbSecret)); |
| 491 | { | 490 | ExitOnFailure(hr, "Failed to write secret length to pipe."); |
| 492 | ExitWithLastError(hr, "Failed to write secret length to pipe."); | ||
| 493 | } | ||
| 494 | 491 | ||
| 495 | if (!::WriteFile(hPipe, wzSecret, cbSecret, &cb, NULL)) | 492 | hr = FileWriteHandle(hPipe, reinterpret_cast<LPCBYTE>(wzSecret), cbSecret); |
| 496 | { | 493 | ExitOnFailure(hr, "Failed to write secret to pipe."); |
| 497 | ExitWithLastError(hr, "Failed to write secret to pipe."); | ||
| 498 | } | ||
| 499 | 494 | ||
| 500 | if (!::WriteFile(hPipe, &dwCurrentProcessId, sizeof(dwCurrentProcessId), &cb, NULL)) | 495 | hr = FileWriteHandle(hPipe, reinterpret_cast<LPCBYTE>(&dwCurrentProcessId), sizeof(dwCurrentProcessId)); |
| 501 | { | 496 | ExitOnFailure(hr, "Failed to write our process id to pipe."); |
| 502 | ExitWithLastError(hr, "Failed to write our process id to pipe."); | ||
| 503 | } | ||
| 504 | 497 | ||
| 505 | // Wait until the elevated process responds that it is ready to go. | 498 | // Wait until the elevated process responds that it is ready to go. |
| 506 | if (!::ReadFile(hPipe, &dwAck, sizeof(dwAck), &cb, NULL)) | 499 | hr = FileReadHandle(hPipe, reinterpret_cast<LPBYTE>(&dwAck), sizeof(dwAck)); |
| 507 | { | 500 | ExitOnFailure(hr, "Failed to read ACK from pipe."); |
| 508 | ExitWithLastError(hr, "Failed to read ACK from pipe."); | ||
| 509 | } | ||
| 510 | 501 | ||
| 511 | // The ACK should match out expected child process id. | 502 | // The ACK should match out expected child process id. |
| 512 | //if (pConnection->dwProcessId != dwAck) | 503 | //if (pConnection->dwProcessId != dwAck) |
| @@ -724,17 +715,8 @@ static HRESULT WritePipeMessage( | |||
| 724 | ExitOnFailure(hr, "Failed to allocate message to write."); | 715 | ExitOnFailure(hr, "Failed to allocate message to write."); |
| 725 | 716 | ||
| 726 | // Write the message. | 717 | // Write the message. |
| 727 | DWORD cbWrote = 0; | 718 | hr = FileWriteHandle(hPipe, reinterpret_cast<LPCBYTE>(pv), cb); |
| 728 | SIZE_T cbTotalWritten = 0; | 719 | ExitOnFailure(hr, "Failed to write message type to pipe."); |
| 729 | while (cbTotalWritten < cb) | ||
| 730 | { | ||
| 731 | if (!::WriteFile(hPipe, pv, (DWORD)(cb - cbTotalWritten), &cbWrote, NULL)) | ||
| 732 | { | ||
| 733 | ExitWithLastError(hr, "Failed to write message type to pipe."); | ||
| 734 | } | ||
| 735 | |||
| 736 | cbTotalWritten += cbWrote; | ||
| 737 | } | ||
| 738 | 720 | ||
| 739 | LExit: | 721 | LExit: |
| 740 | ReleaseMem(pv); | 722 | ReleaseMem(pv); |
| @@ -747,46 +729,25 @@ static HRESULT GetPipeMessage( | |||
| 747 | ) | 729 | ) |
| 748 | { | 730 | { |
| 749 | HRESULT hr = S_OK; | 731 | HRESULT hr = S_OK; |
| 750 | DWORD rgdwMessageAndByteCount[2] = { }; | 732 | BYTE pbMessageAndByteCount[sizeof(DWORD) + sizeof(SIZE_T)] = { }; |
| 751 | DWORD cb = 0; | ||
| 752 | DWORD cbRead = 0; | ||
| 753 | 733 | ||
| 754 | while (cbRead < sizeof(rgdwMessageAndByteCount)) | 734 | hr = FileReadHandle(hPipe, pbMessageAndByteCount, sizeof(pbMessageAndByteCount)); |
| 735 | if (HRESULT_FROM_WIN32(ERROR_BROKEN_PIPE) == hr) | ||
| 755 | { | 736 | { |
| 756 | if (!::ReadFile(hPipe, reinterpret_cast<BYTE*>(rgdwMessageAndByteCount) + cbRead, sizeof(rgdwMessageAndByteCount) - cbRead, &cb, NULL)) | 737 | memset(pbMessageAndByteCount, 0, sizeof(pbMessageAndByteCount)); |
| 757 | { | 738 | hr = S_FALSE; |
| 758 | DWORD er = ::GetLastError(); | ||
| 759 | if (ERROR_MORE_DATA == er) | ||
| 760 | { | ||
| 761 | hr = S_OK; | ||
| 762 | } | ||
| 763 | else if (ERROR_BROKEN_PIPE == er) // parent process shut down, time to exit. | ||
| 764 | { | ||
| 765 | memset(rgdwMessageAndByteCount, 0, sizeof(rgdwMessageAndByteCount)); | ||
| 766 | hr = S_FALSE; | ||
| 767 | break; | ||
| 768 | } | ||
| 769 | else | ||
| 770 | { | ||
| 771 | hr = HRESULT_FROM_WIN32(er); | ||
| 772 | } | ||
| 773 | ExitOnRootFailure(hr, "Failed to read message from pipe."); | ||
| 774 | } | ||
| 775 | |||
| 776 | cbRead += cb; | ||
| 777 | } | 739 | } |
| 740 | ExitOnFailure(hr, "Failed to read message from pipe."); | ||
| 778 | 741 | ||
| 779 | pMsg->dwMessage = rgdwMessageAndByteCount[0]; | 742 | pMsg->dwMessage = *(DWORD*)(pbMessageAndByteCount); |
| 780 | pMsg->cbData = rgdwMessageAndByteCount[1]; | 743 | pMsg->cbData = *(SIZE_T*)(pbMessageAndByteCount + sizeof(DWORD)); |
| 781 | if (pMsg->cbData) | 744 | if (pMsg->cbData) |
| 782 | { | 745 | { |
| 783 | pMsg->pvData = MemAlloc(pMsg->cbData, FALSE); | 746 | pMsg->pvData = MemAlloc(pMsg->cbData, FALSE); |
| 784 | ExitOnNull(pMsg->pvData, hr, E_OUTOFMEMORY, "Failed to allocate data for message."); | 747 | ExitOnNull(pMsg->pvData, hr, E_OUTOFMEMORY, "Failed to allocate data for message."); |
| 785 | 748 | ||
| 786 | if (!::ReadFile(hPipe, pMsg->pvData, pMsg->cbData, &cb, NULL)) | 749 | hr = FileReadHandle(hPipe, reinterpret_cast<LPBYTE>(pMsg->pvData), pMsg->cbData); |
| 787 | { | 750 | ExitOnFailure(hr, "Failed to read data for message."); |
| 788 | ExitWithLastError(hr, "Failed to read data for message."); | ||
| 789 | } | ||
| 790 | 751 | ||
| 791 | pMsg->fAllocatedData = TRUE; | 752 | pMsg->fAllocatedData = TRUE; |
| 792 | } | 753 | } |
| @@ -810,15 +771,11 @@ static HRESULT ChildPipeConnected( | |||
| 810 | LPWSTR sczVerificationSecret = NULL; | 771 | LPWSTR sczVerificationSecret = NULL; |
| 811 | DWORD cbVerificationSecret = 0; | 772 | DWORD cbVerificationSecret = 0; |
| 812 | DWORD dwVerificationProcessId = 0; | 773 | DWORD dwVerificationProcessId = 0; |
| 813 | DWORD dwRead = 0; | ||
| 814 | DWORD dwAck = ::GetCurrentProcessId(); // send our process id as the ACK. | 774 | DWORD dwAck = ::GetCurrentProcessId(); // send our process id as the ACK. |
| 815 | DWORD cb = 0; | ||
| 816 | 775 | ||
| 817 | // Read the verification secret. | 776 | // Read the verification secret. |
| 818 | if (!::ReadFile(hPipe, &cbVerificationSecret, sizeof(cbVerificationSecret), &dwRead, NULL)) | 777 | hr = FileReadHandle(hPipe, reinterpret_cast<LPBYTE>(&cbVerificationSecret), sizeof(cbVerificationSecret)); |
| 819 | { | 778 | ExitOnFailure(hr, "Failed to read size of verification secret from parent pipe."); |
| 820 | ExitWithLastError(hr, "Failed to read size of verification secret from parent pipe."); | ||
| 821 | } | ||
| 822 | 779 | ||
| 823 | if (255 < cbVerificationSecret / sizeof(WCHAR)) | 780 | if (255 < cbVerificationSecret / sizeof(WCHAR)) |
| 824 | { | 781 | { |
| @@ -829,10 +786,8 @@ static HRESULT ChildPipeConnected( | |||
| 829 | hr = StrAlloc(&sczVerificationSecret, cbVerificationSecret / sizeof(WCHAR) + 1); | 786 | hr = StrAlloc(&sczVerificationSecret, cbVerificationSecret / sizeof(WCHAR) + 1); |
| 830 | ExitOnFailure(hr, "Failed to allocate buffer for verification secret."); | 787 | ExitOnFailure(hr, "Failed to allocate buffer for verification secret."); |
| 831 | 788 | ||
| 832 | if (!::ReadFile(hPipe, sczVerificationSecret, cbVerificationSecret, &dwRead, NULL)) | 789 | FileReadHandle(hPipe, reinterpret_cast<LPBYTE>(sczVerificationSecret), cbVerificationSecret); |
| 833 | { | 790 | ExitOnFailure(hr, "Failed to read verification secret from parent pipe."); |
| 834 | ExitWithLastError(hr, "Failed to read verification secret from parent pipe."); | ||
| 835 | } | ||
| 836 | 791 | ||
| 837 | // Verify the secrets match. | 792 | // Verify the secrets match. |
| 838 | if (CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, 0, sczVerificationSecret, -1, wzSecret, -1)) | 793 | if (CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, 0, sczVerificationSecret, -1, wzSecret, -1)) |
| @@ -842,10 +797,8 @@ static HRESULT ChildPipeConnected( | |||
| 842 | } | 797 | } |
| 843 | 798 | ||
| 844 | // Read the verification process id. | 799 | // Read the verification process id. |
| 845 | if (!::ReadFile(hPipe, &dwVerificationProcessId, sizeof(dwVerificationProcessId), &dwRead, NULL)) | 800 | hr = FileReadHandle(hPipe, reinterpret_cast<LPBYTE>(&dwVerificationProcessId), sizeof(dwVerificationProcessId)); |
| 846 | { | 801 | ExitOnFailure(hr, "Failed to read verification process id from parent pipe."); |
| 847 | ExitWithLastError(hr, "Failed to read verification process id from parent pipe."); | ||
| 848 | } | ||
| 849 | 802 | ||
| 850 | // If a process id was not provided, we'll trust the process id from the parent. | 803 | // If a process id was not provided, we'll trust the process id from the parent. |
| 851 | if (*pdwProcessId == 0) | 804 | if (*pdwProcessId == 0) |
| @@ -859,10 +812,8 @@ static HRESULT ChildPipeConnected( | |||
| 859 | } | 812 | } |
| 860 | 813 | ||
| 861 | // All is well, tell the parent process. | 814 | // All is well, tell the parent process. |
| 862 | if (!::WriteFile(hPipe, &dwAck, sizeof(dwAck), &cb, NULL)) | 815 | hr = FileWriteHandle(hPipe, reinterpret_cast<LPCBYTE>(&dwAck), sizeof(dwAck)); |
| 863 | { | 816 | ExitOnFailure(hr, "Failed to inform parent process that child is running."); |
| 864 | ExitWithLastError(hr, "Failed to inform parent process that child is running."); | ||
| 865 | } | ||
| 866 | 817 | ||
| 867 | LExit: | 818 | LExit: |
| 868 | ReleaseStr(sczVerificationSecret); | 819 | ReleaseStr(sczVerificationSecret); |
