<div dir="ltr">On Wed, Mar 23, 2016 at 6:50 PM, Henri Verbeet <span dir="ltr"><<a href="mailto:hverbeet@gmail.com" target="_blank">hverbeet@gmail.com</a>></span> wrote:<br><div><div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">What happens when d3drm_texture_load() is called multiple times on the<br>
same texture? Should that be possible?<br></blockquote><div>On windows, IDirect3DRMTexture*::Load creates a new texture every time you call it on the same texture pointer, effectively losing the old one and creating a leak. The refcount also increases by one every time a new texture is created. So if windows allows this, I guess it's fine. Do let me know if I've missed testing something here though.<br></div> <br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span>> +            HeapFree(GetProcessHeap(), 0, texture->image->palette);<br>
> +        HeapFree(GetProcessHeap(), 0, texture->image);<br>
</span>This seems a bit suspicious. Supposedly the "image" argument to<br>
d3drm3_CreateTexture() can be used to create a texture on an existing<br>
image. The documentation isn't very explicit about it, but suggests<br>
that the image data isn't copied in that case. So I'm not sure the<br>
texture is supposed to be responsible for destroying the image. In<br>
general I think it's not entirely clear how things like<br>
CreateTexture(), LoadTexture() and InitFromFile() etc. are supposed to<br>
interact.<br></blockquote><div>AFAICS on the trace logs of d3drm games ran so far, I haven't encountered CreateTexture spefically. Though you can find usage of CreateTexture in the "Trans" demo from the DX7 SDK, within trans.cpp. After a quick glance I can confirm that it does indeed create a texture on an existing image in memory. The implementation for this should be fairly trivial, but some tests would be needed to check if it does a shallow/deep copy of the image struct (as you mentioned), validation checks, if any, and its refcounting behavior.<br><br>I'm not sure about the Init methods, but so far I haven't been able to see them being used anywhere.<br><br>I've initially decided to prioritize on functions that are actually used by games rather than implementing functions that are probably not used at all in the d3drm apps that ran on wine so far. But I don't mind doing them if they're required somehow, or if a bug reports it.<span><br><br></span><span></span></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span>
> +    size = GetFileSize(hfile, NULL);<br>
> +    if (size == INVALID_FILE_SIZE)<br>
> +    {<br>
> +        DeleteObject(hfile);<br>
> +        return D3DRMERR_BADVALUE;<br>
> +    }<br>
</span>You never use "size" after this, but you probably should. I also think<br>
you meant CloseHandle() instead of DeleteObject().<br></blockquote><div>Right, I could use it to check if the size matches the size specifed in the header field bfSize within BITMAPFILEHEADER. Or maybe there's another use than this?<br><span></span><br><span></span></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span>
> +D3DRMIMAGE *d3drm_create_image(unsigned char *buffer, BITMAPINFO *info, BOOL palette, BOOL upside_down)<br>
> +{<br>
> +    D3DRMPALETTEENTRY *colors = (D3DRMPALETTEENTRY *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 257 * sizeof(*colors));<br>
</span>Is "257" there intentional? The cast is unnecessary. HeapAlloc() can<br>
fail. Do you need HEAP_ZERO_MEMORY here? <br></blockquote><div>I kept it as 257 so that accessing colors[256] shouldn't segfault. The approach I used here is to check if the total number of unique colors is greater than 256, which happens when the 257th unique color is also stored into the array.<br><br>I guess statically allocating it on the stack i.e declaring D3DRMPALETTEENTRY colors[257]; could possibly help avoid the HeapAlloc failures. Makes sense since the 257 is hard-coded anyways. Should I do that? Or is the HeapAlloc a better approach?<br></div><div><br></div><div>As for HEAP_ZERO_MEMORY, see below.<span></span><br><span></span></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span>
</span>This is unsafe. Consider e.g. what happens when the header gives you<br>
0x10000 for width and height.<br></blockquote><div>You're right. d3drm returns D3DRMERR_BADVALUE for textures with width and height that large. I'll add a test accordingly.<br>I'll also be adding validation checks for bitmap format from the header, as you mentioned.<br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span><br>
> +    buffer1 = image->buffer1;<br>
> +    memset(buffer1, 255, sizeof(unsigned char) * bpl * h);<br>
</span>You just initialised the memory with HEAP_ZERO_MEMORY, and now you're<br>
overwriting it again. At least one of these two initialisations is<br>
unnecessary, and quite possibly both of them.<br>
<br></blockquote><div>I actually intended to initialize it to 0xFF rather than zero. But you're right about the alloc's being unnecessary. I'll remove both initializations, and keep the default initialization to 0xFF as the byte padding in 32bpp bitmaps are all 0xFF.<br></div><div><br></div><div>I also agree with the rest of the changes and will submit another patch very soon.<br></div><div><br></div><div>Thanks for the detailed review! Really appreciate it.<br><br></div><div>Cheers,<br></div><div>Aaryaman<br></div></div><br></div></div></div></div>