diff options
Diffstat (limited to '')
-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); |