-typedef struct {
- guint16 data_len;
- guint16 value_len;
- guint16 type;
- gunichar2 *key;
-} version_data;
-
-/* Returns a pointer to the value data, because theres no way to know
- * how big that data is (value_len is set to zero for most blocks :-()
- */
-static gpointer process_get_versioninfo_block (gpointer data,
- version_data *block)
-{
- block->data_len=*((guint16 *)data);
- data = (char *)data + sizeof(guint16);
- block->value_len=*((guint16 *)data);
- data = (char *)data + sizeof(guint16);
-
- /* No idea what the type is supposed to indicate */
- block->type=*((guint16 *)data);
- data = (char *)data + sizeof(guint16);
- block->key=((gunichar2 *)data);
-
- /* skip over the key (including the terminator) */
- data=((gunichar2 *)data)+(unicode_chars (block->key)+1);
-
- /* align on a 32-bit boundary */
- data=(gpointer)((char *)data + 3);
- data=(gpointer)((char *)data - (GPOINTER_TO_INT(data) & 3));
-
- return(data);
-}
-
-/* Returns a pointer to the byte following the Var block */
-static gpointer process_read_var_block (MonoObject *filever, gpointer data_ptr,
- guint16 data_len)
-{
- /* Not currently interested in the VarFileInfo block. This
- * might change if language support is needed for file version
- * strings (VarFileInfo contains lists of supported
- * languages.)
- */
- version_data block;
-
- /* data_ptr is pointing at a Var block of length data_len */
- data_ptr=process_get_versioninfo_block (data_ptr, &block);
- data_ptr=((guchar *)data_ptr)+block.value_len;
-
- return(data_ptr);
-}
-
-/* Returns a pointer to the byte following the String block, or NULL
- * if the data read hits padding. We can't recover from this because
- * the data length does not include padding bytes, so it's not
- * possible to just return the start position + length.
- */
-static gpointer process_read_string_block (MonoObject *filever,
- gpointer data_ptr,
- guint16 data_len,
- gboolean store)
-{
- version_data block;
- guint16 string_len=28; /* Length of the StringTable block */
-
- /* data_ptr is pointing at an array of one or more String
- * blocks with total length (not including alignment padding)
- * of data_len.
- */
- while(string_len<data_len) {
- gunichar2 *value;
-
- /* align on a 32-bit boundary */
- data_ptr=(gpointer)((char *)data_ptr + 3);
- data_ptr=(gpointer)((char *)data_ptr -
- (GPOINTER_TO_INT(data_ptr) & 3));
-
- data_ptr=process_get_versioninfo_block (data_ptr, &block);
- if(block.data_len==0) {
- /* We must have hit padding, so give up
- * processing now
- */
-#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION
- ": Hit 0-length block, giving up");
-#endif
- return(NULL);
- }
-
- string_len=string_len+block.data_len;
- value=(gunichar2 *)data_ptr;
- /* Skip over the value */
- data_ptr=((gunichar2 *)data_ptr)+block.value_len;
-
- if(store==TRUE) {
- if (unicode_string_equals (block.key, "Comments")) {
- process_set_field_string (filever, "comments", value, unicode_chars (value));
- } else if (unicode_string_equals (block.key, "CompanyName")) {
- process_set_field_string (filever, "companyname", value, unicode_chars (value));
- } else if (unicode_string_equals (block.key, "FileDescription")) {
- process_set_field_string (filever, "filedescription", value, unicode_chars (value));
- } else if (unicode_string_equals (block.key, "FileVersion")) {
- process_set_field_string (filever, "fileversion", value, unicode_chars (value));
- } else if (unicode_string_equals (block.key, "InternalName")) {
- process_set_field_string (filever, "internalname", value, unicode_chars (value));
- } else if (unicode_string_equals (block.key, "LegalCopyright")) {
- process_set_field_string (filever, "legalcopyright", value, unicode_chars (value));
- } else if (unicode_string_equals (block.key, "LegalTrademarks")) {
- process_set_field_string (filever, "legaltrademarks", value, unicode_chars (value));
- } else if (unicode_string_equals (block.key, "OriginalFilename")) {
- process_set_field_string (filever, "originalfilename", value, unicode_chars (value));
- } else if (unicode_string_equals (block.key, "PrivateBuild")) {
- process_set_field_string (filever, "privatebuild", value, unicode_chars (value));
- } else if (unicode_string_equals (block.key, "ProductName")) {
- process_set_field_string (filever, "productname", value, unicode_chars (value));
- } else if (unicode_string_equals (block.key, "ProductVersion")) {
- process_set_field_string (filever, "productversion", value, unicode_chars (value));
- } else if (unicode_string_equals (block.key, "SpecialBuild")) {
- process_set_field_string (filever, "specialbuild", value, unicode_chars (value));
- } else {
- /* Not an error, just not interesting
- * in this case
- */
- }
- }
- }
-
- return(data_ptr);
-}