Bug 1403180: Fix StripHandlerFromOBJREF for VT_DISPATCH on Windows 7. r?aklotz draft
authorJames Teh <jteh@mozilla.com>
Mon, 23 Oct 2017 15:37:24 +1000
changeset 684586 c84ec8c9a939c9530762540f940386564336f7ab
parent 684511 ce1a86d3b4db161c95d1147676bbed839d7a4732
child 736901 984d83ac0993214327988495ff3a7ce2c6d190b1
push id85656
push userbmo:jteh@mozilla.com
push dateMon, 23 Oct 2017 05:51:48 +0000
reviewersaklotz
bugs1403180
milestone58.0a1
Bug 1403180: Fix StripHandlerFromOBJREF for VT_DISPATCH on Windows 7. r?aklotz StripHandlerFromOBJREF shortens the OBJREF by sizeof(CLSID), so it needs to seek the stream back after tweaking the OBJREF. Previously, this was done using a relative seek. Unfortunately, for some reason I can't fathom on Windows 7, this doesn't work when marshaling for VT_DISPATCH. The Seek call succeeds, but either does nothing or sets the stream position to a garbage value. Instead, we now use an absolute seek, which seems to behave. This was breaking IAccessible::accNavigate and AccessibleChildren on Windows 7. MozReview-Commit-ID: FEH93oiyP5R
ipc/mscom/Objref.cpp
--- a/ipc/mscom/Objref.cpp
+++ b/ipc/mscom/Objref.cpp
@@ -298,19 +298,24 @@ StripHandlerFromOBJREF(NotNull<IStream*>
   // The difference between a OBJREF_STANDARD and an OBJREF_HANDLER is
   // sizeof(CLSID), so we'll zero out the remaining bytes.
   CLSID zeroClsid = {0};
   hr = aStream->Write(&zeroClsid, sizeof(CLSID), &bytesWritten);
   if (FAILED(hr) || bytesWritten != sizeof(CLSID)) {
     return false;
   }
 
-  // Back up to just before the zeros we just wrote
-  seekTo.QuadPart = -static_cast<int64_t>(sizeof(CLSID));
-  return SUCCEEDED(aStream->Seek(seekTo, STREAM_SEEK_CUR, nullptr));
+  // Back up to the end of the tweaked OBJREF.
+  // There are now sizeof(CLSID) less bytes.
+  // Bug 1403180: Using -sizeof(CLSID) with a relative seek sometimes
+  // doesn't work on Windows 7.
+  // It succeeds, but doesn't seek the stream for some unknown reason.
+  // Use an absolute seek instead.
+  seekTo.QuadPart = aEndPos - sizeof(CLSID);
+  return SUCCEEDED(aStream->Seek(seekTo, STREAM_SEEK_SET, nullptr));
 }
 
 uint32_t
 GetOBJREFSize(NotNull<IStream*> aStream)
 {
   // Make a clone so that we don't manipulate aStream's seek pointer
   RefPtr<IStream> cloned;
   HRESULT hr = aStream->Clone(getter_AddRefs(cloned));