Results 1 to 8 of 8

Thread: [RESOLVED] DWord Alignment of VB Resource File Entries

  1. #1

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Resolved [RESOLVED] DWord Alignment of VB Resource File Entries

    I've seen posts regarding this topic from time to time. So, trying to get a definitive answer from you guys/gals from your personal, verifiable experiences.

    Can VB change the reported actual size of an individual resource once it is compiled into the application?

    FYI. I know that prior to SP6, this was a bug and supposedly fixed with SP6. That bug resulted in VB padding the resource, as needed, 1 to 3 vbNullChar bytes to force dword alignment. That in itself is not the problem, the problem is if the size of the resource was adjusted to match. This bug appears primarily with HTML/XML resources (RT_HTML/RT_MANIFEST respectively). The resource size includes the null characters and null characters are not valid in that context.

    Note: I've seen a couple of Elroy's posts regarding this topic, but do not know if they were pre-SP6 or not. In his case, his concern was checksums/CRCs when extracting data from a resource to file. If the resource was padded and size was modified to reflect the padding, then the extracted resource would be 1-3 bytes larger than original; resulting in a failed checksum/CRC validation.

    Edited: msdn comments about the pre-SP6 padding bug
    Last edited by LaVolpe; Oct 27th, 2017 at 09:38 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  2. #2

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: DWord Alignment of VB Resource File Entries

    Hmmm, kinda answered this one myself. I found an older resource file with several binary entries and tested it compiled/uncompiled. There were 9 custom resources in it and all but one (in red) were NOT dword aligned sizes. Here are the results before/after compiling. The changed values (in blue) are dword-aligned values. But not all unaligned values were changed; most were not. The sizes reported when compiled were checked with both APIs and VB's LoadResData. The uncompiled sizes were checked both by manual parsing of res file and VB's LoadResdata.

    Resource Name Uncompiled Size Compiled Size
    102LAVOLPE 87654 87656
    103LAVOLPE 97254 97256
    104LAVOLPE 35521 35521
    106LAVOLPE 9662 9662
    107LAVOLPE 101566 101568
    108LAVOLPE 3136 3136
    109LAVOLPE 65405 65405
    111LAVOLPE 766 766
    112LAVOLPE 49611 49611
    FYI: SP6 is installed

    Edited: Now I can see why Elroy was concerned regarding checksum/CRC. Also, if any of those resources that had their sizes changed were XML/HTML files, the reported size would include null bytes which could result in failure to parse/read the extracted file (per msdn)

    Regarding caching actual size of resource, Elroy mentioned he did that by hardcoding the actual size within the project. Likewise, one could rename the resource with the size so it's always known, i.e., CUSTOM: "HOWTO(97254)". Another option would be to rewrite the file before adding it to the resource, preceding it with a 4-byte value that contains the actual size. When LoadResData() is used, read the 1st 4 bytes, and write to file the rest of the array, required length only.
    Last edited by LaVolpe; Oct 28th, 2017 at 10:19 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: DWord Alignment of VB Resource File Entries

    A factor that can enter into this is the resource's Type and Name (or Id). When a string value is used these can change the length of the item's header in the resource file and compiled-in block in the PE file.

    This might explain where the extra padding can come from, since each item including its header is supposed to fall on a DWORD boundary.

    Another issue might be how the VB6 IDE Resource Editor add-in manages data. It might use logic similar to the IDE's cheat code (for runs in the IDE) which does not seem to make use of the API calls supporting resources.

  4. #4

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: DWord Alignment of VB Resource File Entries

    Regarding string res IDs. I considered that, but if you notice, each are the same length; therefore, I think one would expect the same results for each. Besides a resource file has two primary size variables:

    1. Header size which includes the resource name and ID and is always a DWord value due to the required padding within the header's sub-blocks. In the example above, each header size would be identical. The data size is a sub-block.

    2. Data size which includes the actual resource size. And stating the obvious, each of the above are different. And what I liked about that res file for a test case, is that it included all 4 possible alignment scenarios: dword, off-by 1, 2, & 3

    The Header Block is always dword aligned naturally due to its sub-block requirements. The Data Block is not required to be. Since the header block is always aligned, the data block naturally starts on aligned boundary. However, since data is not required to be aligned, padding may be needed to allow the next header to start on aligned boundary. The Data Block size needs to be rounded up to dword alignment for navigation, but shouldn't be written/adjusted like that. The data size should be the actual resource size, without considering padding. Padding is part of the entire resource block, but not the data itself. In short:
    b() = LoadResData(101,"Custom") in IDE may not be same size array when compiled

    Navigating between uncompiled resources is a simple matter of (HeaderSize + DwordAlign(DataSize)) to jump to the next resource.

    I think what could be frustrating a bit is that Microsoft said it fixed the padding issue with SP6. But maybe it only fixed it for RT_HTML & RT_MANIFEST? Maybe this is a PE thing, within the PE headers? But my primary question is answered I think -- reported size of a compiled resource within VB is not guaranteed to be the actual size of the resource. Reported size could be 1, 2 or 3 bytes bigger than actual

    Edited: Just for grins, changed all the resource IDs to integers, i.e., 101-109. Same results. But there is one thing that may not be a coincidence. Maybe size of resource is at play. If you notice, the 3 largest ones had their sizes modified. So, maybe there is some hard-set value where VB changes the size?

    Edited yet again. Just found a post by Elroy that mentions a fixed size value where rounding up to dword values will occur. The magic number: 65520 (&HFFF0) bytes or greater.
    Last edited by LaVolpe; Oct 28th, 2017 at 10:46 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  5. #5

    Thread Starter
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: DWord Alignment of VB Resource File Entries

    If anyone wants to play along...
    1. Create a new project
    2. Add a command button
    3. Add a resource file and add several "CUSTOM" resources, starting with 101
    Edited: add one or more > 65kb
    4. Compile the project (it'll never be run and can be deleted when done playing)
    5. Add the compiled project's path/file name to the code below
    6. Add the number of custom resources to the code below
    7. Run the project in IDE. The compiled version is only used to query its compiled resource sizes
    Code:
    Option Explicit
    
    Private Const LOAD_LIBRARY_AS_DATAFILE As Long = &H2
    Private Declare Function LoadLibraryEx Lib "kernel32.dll" Alias "LoadLibraryExA" (ByVal lpLibFileName As String, ByVal hFile As Long, ByVal dwFlags As Long) As Long
    Private Declare Function FreeLibrary Lib "kernel32.dll" (ByVal hLibModule As Long) As Long
    Private Declare Function FindResource Lib "kernel32.dll" Alias "FindResourceA" (ByVal hInstance As Long, ByVal lpName As String, ByVal lpType As String) As Long
    Private Declare Function SizeofResource Lib "kernel32.dll" (ByVal hInstance As Long, ByVal hResInfo As Long) As Long
    
    Private Sub Command1_Click()
        ' add a resource file to this project, add a number of "CUSTOM" resources
        ' then compile the project and add its path/filename below
        ' provide the number of resources below, starting with 101
        
        ' This project always run uncompiled. The compiled version never run
        Const NrResources = 10
        Const EXEFileName As String = "C:\..."
        
        GetResourceSizes_Uncompiled NrResources
        Debug.Print
        GetResourceSizes_Compiled EXEFileName, NrResources
        
    End Sub
    
    Private Sub GetResourceSizes_Compiled(EXEpath As String, nrResourcesStartingWith101 As Long)
        Dim hMod As Long, hRes As Long
        Dim lSize As Long, i As Long
        
        hMod = LoadLibraryEx(EXEpath, 0&, LOAD_LIBRARY_AS_DATAFILE)
        If hMod = 0 Then Stop
        For i = 101 To nrResourcesStartingWith101 + 100
            hRes = FindResource(hMod, "#" & CStr(i), "CUSTOM")
            If hRes Then
                Debug.Print "cmp: CUSTOM "; i, SizeofResource(hMod, hRes)
            End If
        Next
        FreeLibrary hMod
                
    End Sub
    
    Private Sub GetResourceSizes_Uncompiled(nrResourcesStartingWith101 As Long)
    
        Dim i As Long, b() As Byte
        
        For i = 101 To nrResourcesStartingWith101 + 100
            On Error Resume Next
            b() = LoadResData(i, "CUSTOM")
            If Err Then
                Err.Clear
            Else
                Debug.Print "raw: CUSTOM "; i, UBound(b) + 1
            End If
        Next
    End Sub
    Oops. Typo in final LoadResData line. Fixed
    Last edited by LaVolpe; Oct 27th, 2017 at 10:01 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  6. #6
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,915

    Re: [RESOLVED] DWord Alignment of VB Resource File Entries

    Hi all,

    Sorry I've been a bit AWOL. We lost a loved family dog on Saturday, but things are slowly getting back to normal (or, at least our new normal).

    Yes, this "resource file" thing is an issue I've struggled with for years. I literally stuff 100s of things in my primary project's .RES file. I do this to keep the project both portable and singular (starting with a single EXE file).

    I'll continue to use the resource editor add-in, because of its simplicity. And, because I use Word and Excel automation for 99% of my reporting needs, I am rather regularly making changes to various DOC, XLS, DOT, XLT, DOCX, XLSX, DOTX, & XLTX files include in the resources.

    As outlined by LaVolpe, it's only the XML type files (DOCX, XLSX, DOTX, & XLTX) that give me problems. And even then, only when they're over 65520 filesize bytes.

    Also as outlined by LaVolpe, I just grab the actual size of these files when I place them into my RES file (via the add-in), and then hardcode these sizes in my code. At present, this is only 12 files:

    Code:
    
    Private Sub InitializeCustomSizes()
        ' Even though this is a _Gen_ module, the following must be customized for each application.
        '
        ' Any file larger than 65520 that's NOT sized as a multiple of 4 bytes will not unpack correctly.
        '
        Static bInitialized As Boolean
        '
        If bInitialized Then Exit Sub
        '
        '
        ' The actual SIZE, and NOT "size on disk".
        '
        ReDim ResFileSizes(1 To 12)
        '
        ResFileSizes(1).FileName = "EmgReport.xltx":                        ResFileSizes(1).FileSize = 73294
        ResFileSizes(2).FileName = "EmgNorms.xltx":                         ResFileSizes(2).FileSize = 10274
        ResFileSizes(3).FileName = "Foot Pressure (new) (left).dotx":       ResFileSizes(3).FileSize = 182606
        ResFileSizes(4).FileName = "Foot Pressure (new) (leftright).dotx":  ResFileSizes(4).FileSize = 185347
        ResFileSizes(5).FileName = "Foot Pressure (new) (right).dotx":      ResFileSizes(5).FileSize = 182842
        ResFileSizes(6).FileName = "MotionGraphsNew.xltm":                  ResFileSizes(6).FileSize = 1331553
        ResFileSizes(7).FileName = "OldHoustonNorms.xlsx":                  ResFileSizes(7).FileSize = 134593
        ResFileSizes(8).FileName = "MotionNorms.xltx":                      ResFileSizes(8).FileSize = 63975
        ResFileSizes(9).FileName = "Balance.dotx":                          ResFileSizes(9).FileSize = 32765
        ResFileSizes(10).FileName = "Spine Report.dotx":                    ResFileSizes(10).FileSize = 97712
        ResFileSizes(11).FileName = "SpineNorms.xltx":                      ResFileSizes(11).FileSize = 12078
        ResFileSizes(12).FileName = "SpineReportGraph.xltx":                ResFileSizes(12).FileSize = 48044
        '
        bInitialized = True
    End Sub
    
    
    (Okay, I know that all of those aren't over 65520, but I've just gotten into the habit of doing this for all my XML-type files.)

    However, truth be told, this is terribly inconvenient. And, on more than one occasion, I've forgotten to update this little procedure before compiling.

    In the past, I've worked long-and-hard to come up with a better solution to this, but haven't found one. I've become completely convinced that the actual file size (when they go over 65520) just isn't in the compiled RES file (and subsequently the EXE).

    However, I do like LaVolpe's idea of putting the actual filesize in the file's name. That would be more in-my-face, and would help me to remember to change it when the file is changed. Also, I'm thinking of writing some quick-and-dirty utility that I could drag the file onto, and it would change/update its name with the correct file size.

    The only problem that leaves me is how to find the resource without knowing its exact name. For instance, let's take one of the above. Let's say I'm looking for "EmgReport.xltx". However, with the new scheme, I've placed it into my resources as "EmgReport[73294].xltx"...

    Name:  resprob.png
Views: 390
Size:  4.9 KB

    ...but with the addition of the new "[73294]". How would I find that resource without knowing the addition to the filename?

    LaVolpe: I apologize if this is hijacking your thread, but it is closely on-topic. If you'd like, I'll ask the moderators to start a new thread with this post.

    Best Regards,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  7. #7
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,915

    Re: [RESOLVED] DWord Alignment of VB Resource File Entries

    Okay, I've resolved my own issue, with some help from LaVolpe.

    I'm in catch-up mode, and just got time to study LaVolpe's code for detecting whether a resource file exists. And it works the same in the IDE and compiled, which was what I was after.

    That worked perfectly. In fact, it reminded me that (for a resource dump), I already had similar code. Without needing to load the resources, LaVolpe's code gave me a way to check for the existence of a resource file.

    And, with just a touch of tweaking, I'll be able to use it for the problem I outlined in post #6, above. So, I'm good to go.

    Best Regards,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  8. #8
    PowerPoster
    Join Date
    Jan 2020
    Posts
    5,541

    Re: [RESOLVED] DWord Alignment of VB Resource File Entries

    I wrote a module by myself. All the files in the resource are written in a notepad file with the format:
    Resource name Size File path
    Resource name Size File path
    Resource name Size File path
    Add this file size list to the resource, the name is: ResFileSize
    When opening the software, read this resource first, then parse it into a dictionary or collection object, and then read files in other resources, and then reduce the byte array according to this list.

    I have encountered a situation where sometimes it is necessary to increase or decrease a few bytes to keep the consistency. I never know why, but this time I realized that the original content was mistaken by the resource tool.
    VB6 has been used for so many years. In addition to not supporting 64-bit EXE compilation, many Internet senior programmers have added multithreading, standard DLL generation and other functions to him, as well as powerful OLEEXP.TLB, OLELIB.TLB and so on.
    Almost perfect product with few bugs.
    VisualFreebasic developed by the Chinese now has many problems. After all, individuals are only developing based on interest, and the development progress is slow. If there are 30-200 engineers in the development team like Microsoft, more than 95% of the bugs will be fixed.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width