Created attachment 21925 [details] Contains test code 'pe.java' and several sample .PPT's containing a single slide with an embedded Flash OCX control (which represent an ExOleObStg record) I've been working with hslf reading/writing .PPT files with some success. However, I want to change a property of an embedded Flash ActiveX control. PowerPoint binary format stores this as a docfile stream inside the PowerPoint file within a record of type ExOleObjStg (record type #4113). You can get at the uncompressed stream, of course, by calling getData() on the specific record object. I can get at the data that represents the ActiveX Flash control just fine and can see using a hex editor some various properties. However, when I try to update any characters in-place and save the .PPT back out, it often will open with an error (strangely, sometimes changing a single byte does not result in an error). Here is a sample of a stream that is storing the ActiveX data that that Flash OCX apparently reads: http://skitch.com/speby/k1s3/a The above example shows a part of the data inside after calling getData() on an ExOleObjStg which is the embedded Flash ActiveX (.OCX) data. The Movie property, in the above example is set to lowercase 'a' for the curious. The above example is from examining the 'oledump' file generated from the text code that is attached when running it against 'a.ppt'. I have gone through a few basic reverse-engineering trials whereby I save a .PPT with a single Flash ActiveX control and only change the movie property. One .PPT with a Flash Movieproperty 'a', one with Movie property 'b', and so on for a few more. The only differences in the output I see above between each of those successive iterations is in the 4 bytes at offset 1008 (2A 55 00 00) and the 4 bytes right after at offset 100C (B4 3A 00 00). That's all that changes. Given this and the very small changes I was making in each, the values that were being saved out at those two offsets are wildly different. My only conclusion, thus far, is that those 8 bytes represent some kind of checksum, perhaps, but have no way to practically verify that in any reasonable amount of time. What I don't know is whether those are specific to the Flash OCX control itself or are they specific to the ActiveX IStorage interface on Windows or something else entirely? You can see the differences when running the test code against 'a.ppt' and grabbing the 'oledump' and comparing it to when running \the test code against 'b.ppt' and its 'oledump' output. My guess is that ultimately this is fairly simple checksum of some sort but without knowing which one, it is difficult to proceed. The ultimate goal is to be able to modify the properties of the OCX control with the POI library. See the following screenshot for the properties within PowerPoint. The 'Movie' property is the one I am modifying specifically in this report: http://skitch.com/speby/khep/microsoft-windows-xp
For further information, the following is an example of the contents from activeX1.xml from inside of a PowerPoint 2007 presentation: <?xml version="1.0" encoding="UTF-8" standalone="no"?> <ax:ocx ax:classid="{D27CDB6E-AE6D-11CF-96B8-444553540000}" ax:persistence="persistPropertyBag" xmlns:ax="http://schemas.microsoft.com/office/2006/activeX" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><ax:ocxPr ax:name="_cx" ax:value="23707"/><ax:ocxPr ax:name="_cy" ax:value="17357"/><ax:ocxPr ax:name="FlashVars" ax:value=""/><ax:ocxPr ax:name="Movie" ax:value="http://www.polleverywhere.com/multiple_choice_polls/MTU0MTkzMDg2.swf"/><ax:ocxPr ax:name="Src" ax:value="thisisatest"/><ax:ocxPr ax:name="WMode" ax:value="Window"/><ax:ocxPr ax:name="Play" ax:value="-1"/><ax:ocxPr ax:name="Loop" ax:value="-1"/><ax:ocxPr ax:name="Quality" ax:value="High"/><ax:ocxPr ax:name="SAlign" ax:value=""/><ax:ocxPr ax:name="Menu" ax:value="-1"/><ax:ocxPr ax:name="Base" ax:value=""/><ax:ocxPr ax:name="AllowScriptAccess" ax:value=""/><ax:ocxPr ax:name="Scale" ax:value="ShowAll"/><ax:ocxPr ax:name="DeviceFont" ax:value="0"/><ax:ocxPr ax:name="EmbedMovie" ax:value="0"/><ax:ocxPr ax:name="BGColor" ax:value=""/><ax:ocxPr ax:name="SWRemote" ax:value=""/><ax:ocxPr ax:name="MovieData" ax:value=""/><ax:ocxPr ax:name="SeamlessTabbing" ax:value="1"/><ax:ocxPr ax:name="Profile" ax:value="0"/><ax:ocxPr ax:name="ProfileAddress" ax:value=""/><ax:ocxPr ax:name="ProfilePort" ax:value="0"/><ax:ocxPr ax:name="AllowNetworking" ax:value="all"/><ax:ocxPr ax:name="AllowFullScreen" ax:value="true"/></ax:ocx> Notice the x:persistence="persistPropertyBag". There is more information about how this works but my knowledge of these Windows-based OLE APIs is limited. I would imagine, though, that this interface is involved with the persistence of ActiveX properties such as the ones I am defining in this bug report.
Yegor comments in bug 43376 that ExOleObjStg is not yet supported by HSLF and that it is hard. He is willing to help someone try to do so.
Wow, thought this was basically a dead bug, although it mostly is. After I didn't hear much back on this thread, I continued to try and decode a repeatable pattern from how the ExLoeObjStg record was saving the bytes that represented the properties for the ActiveX control but to no avail. Eventually, I gave up and went a different direction completely to get around what I was trying to accomplish. Oh well! By the time the POI project has supported the decoding of ExOleObjStg records (if ever), the entire binary Office formats will mostly be history.
No progress in years, therefore closing this bug for now until someone with interest in this feature can provide some initial patches/ideas.