mdsteele / rust-msi

Rust library for reading/writing Windows Installer (MSI) files
MIT License
58 stars 11 forks source link

InvalidData: Invalid field size for integer column (1) #8

Closed ikrivosheev closed 3 years ago

ikrivosheev commented 3 years ago

Hello, thanks a lot for the library! I got error:

Custom { kind: InvalidData, error: "Invalid field size for integer column (1)" }'

I try to open the file: bc7b6b32157ed65023bb251e177f78480490ec1fa53eb54ec4441e8a44f33f36.zip

I dump tables using: orca - MSI.zip

mdsteele commented 3 years ago

Thanks for the report! I've dug into it a bit. Brain-dump follows:

Looking at the file you've linked, the problematic column appears to be the "NewService" column in the "ServiceConfig" table. ServiceConfig doesn't seem to be one of the standard tables, so I'm not sure what it's for (there's MsiServiceConfig, but it seems to have a totally different schema). Here's the schema I'm seeing for ServiceConfig in that file:

ServiceConfig
  ServiceName                  *VARCHAR(72)
  Component_                    VARCHAR(72)
  NewService                    [what should this be?]
  FirstFailureActionType        VARCHAR(32)
  SecondFailureActionType       VARCHAR(32)
  ThirdFailureActionType        VARCHAR(32)
  ResetPeriodInDays             INTEGER?
  RestartServiceDelayInSeconds  INTEGER?
  ProgramCommandLine            VARCHAR(255)?
  RebootMessage                 VARCHAR(255)?

The column type bitfield for the NewService column in that MSI file is 0x501, which would seem to correspond to a 1-byte-wide integer, which I didn't think was a valid column type in MSI databases—my understanding was that integer columns in MSI database are always either 2 or 4 bytes wide. And looking at the raw data for that table, as far as I can tell, that column is actually being stored as a 2-byte-wide integer.

So it seems that the solution would be to interpret a "1-byte-wide integer" column the same as a 2-byte-wide integer column, at least for the purposes of reading the data. When I make that change, the msi crate is able to read the file just fine, and get reasonable-seeming data out of the ServiceConfig table:

ServiceName              Component_             NewService  FirstFailureActionType  SecondFailureActionType  ThirdFailureActionType  ResetPeriodInDays  RestartServiceDelayInSeconds  ProgramCommandLine  RebootMessage  
-----------------------  ---------------------  ----------  ----------------------  -----------------------  ----------------------  -----------------  ----------------------------  ------------------  -------------  
"[WPFFontCache_x86_ID]"  "WPFFontCacheEXE_x86"  1           "restart"               "restart"                "none"                  1                  NULL                          NULL                NULL  
ikrivosheev commented 3 years ago

@mdsteele thank you for fix, I will test this!