Author Topic: CObjectFile - create .obj files  (Read 17134 times)

0 Members and 1 Guest are viewing this topic.

Offline sapero

  • Senior Developer
  • Hero Member
  • *****
  • Posts: 1291
CObjectFile - create .obj files
« on: March 26, 2006, 10:56:59 AM »
While converting C headers have found many only defined GUID's:
DEFINE_GUID(LIBID_ASPTypeLibrary,0xD97A6DA0,0xA85C,0x11cf,0x83,0xAE,0x00,0xA0,0xC9,0x0C,0x2B,0xD8);

Also needed an automation class to pick all the guids (and strings) and create a static library with it.
Class is defined as follows:
Code: [Select]
class CObjectFile
{
declare CObjectFile();
declare _CObjectFile();

declare AddSection(string SectionName, int SectionFlags),BOOL;
// AddSymbol: set DuplicateData to TRUE if the data (SymbolData) will be deleted after calling this method
declare AddSymbol(string SymbolName, int SectionIndex, void *SymbolData, int DataSize, opt BOOL DuplicateData),BOOL;
declare Save(string path),BOOL;
declare Cleanup();

//private
declare GetAligned(int value),int;
declare AlignFileOffset(),int;
declare WriteHeader();
declare WriteSections();
declare WriteSymbols();
declare WriteStringTable();
declare WriteRawData(int section);
declare GetSectionStorage(int section),pointer;
declare GetStringTableSize(),int;
declare GetSectionDataSize(int section),int;

COFF_OBJHEADER m_header;
CPointerList   m_sections;
CPointerList   m_symbols;
HANDLE         m_hFile;
int            m_StringTableSize;
}

the usage is very easy:
1. Create data to pick into library (here three guids), this can be any accesible memory:
Code: [Select]
// 7DE68B4C-138C-4CD5-9236-E4DAB28EB5AD
#emit _IID_IT     dd 0x7DE68B4C, 0x4CD5138C, 0xDAE43692, 0xADB58EB2
// 2B4F1847-F537-472C-9806-A3F558256256
#emit _IID_ITest  dd 0x2B4F1847, 0x472CF537, 0xF5A30698, 0x56622558
// 984078D5-69A0-428C-94EA-D760B9B94FDD
#emit _CLSID_Test dd 0x984078D5, 0x428C69A0, 0x60D7EA94, 0xDD4FB9B9
declare _IID_IT;
declare _IID_ITest;
declare _CLSID_Test;

Create class instance and insert the above guids into .data section:
Code: [Select]
global sub main()
{
CObjectFile obj;
obj.AddSection(".data", IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE);

// add three guids
obj.AddSymbol(
"_IID_IT", // symbol name
1,         // section index
&_IID_IT,  // pointer to raw data
16,        // size of data
false      // data is static
);
obj.AddSymbol(
"_IID_ITest",// symbol name
1,           // section index
&_IID_ITest, // pointer to raw data
16,          // size of data
false        // data is static
);
obj.AddSymbol(
"_CLSID_Test",// symbol name
1,            // section index
&_CLSID_Test, // pointer to raw data
16,           // size of data
false         // data is static
);

To add a string:
Code: [Select]
obj.AddSymbol(
"MyGlobalString",   // symbol name
1,                                 // section index
"blah, it's MyGlobalString",       // pointer to raw data
len("blah, it's MyGlobalString")+1,// size of data
false                              // data is static
);

A temporary string from heap:
Code: [Select]
obj.AddSymbol(
"MyHeapString",               // symbol name
1,                            // section index
"blah, it's " + "MyHeap"+"String",       // pointer to raw data
len("blah, it's " + "MyHeap"+"String")+1,// size of data
true                                     // data is temporary
);

Create another section:
Code: [Select]
obj.AddSection(".text", IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE);
obj.AddSymbol(
"_IID_ITest2",// symbol name
2,            // section index
&_IID_ITest,  // pointer to raw data
16,           // size of data
false         // data is static
);

ok, ok, save it now, usually we create object file with only one-two guids (IID+CLSID)
Code: [Select]
obj.Save(GetStartPath() + "_IID_Test.obj");

// show dump of created object file (optional)
system("cmd /k link /dump /all _IID_Test.obj");
return;
}
This object creator has a big plus: object file is pretty small: with one guid it takes 112 bytes
(16 bytes for guid, x for name, 86 for headers);
Here is no debug info, no relocations and no linenumbers.

Also we have an object file that exports some data, lets make use of it! (console app)
Code: [Select]
struct GUID {int x[4];}
extern int StringFromCLSID(GUID *g, void *ppstr);
extern int CoTaskMemFree(void *mem);
extern int printf(...);
extern int _getch();

#use "D:\\Aurora\\forum\\_IID_Test.obj" // change it

extern _IID_IT as GUID;
extern _IID_ITest as GUID;
extern _CLSID_Test as GUID;
extern _IID_ITest2 as GUID;
extern MyGlobalString as string;
extern MyHeapString as string;

global sub main()
{
GUID g;
string *lpsz;

StringFromCLSID(_IID_IT, &lpsz);
printf("_IID_IT      : %S\n", lpsz);
CoTaskMemFree(lpsz);

StringFromCLSID(_IID_ITest, &lpsz);
printf("_IID_ITest : %S\n", lpsz); // unicode
CoTaskMemFree(lpsz);

StringFromCLSID(_IID_ITest2, &lpsz);
printf("_IID_ITest2: %S\n", lpsz);
CoTaskMemFree(lpsz);

StringFromCLSID(_CLSID_Test, &lpsz);
printf("_CLSID_Test: %S\n", lpsz);
CoTaskMemFree(lpsz);

print("MyGlobalString: ", MyGlobalString);
print("MyHeapString   : ", MyHeapString);
return _getch();
}
hey, it links and shows correct data! ;D

EDIT: removed bad characters from text.
« Last Edit: November 01, 2010, 02:11:38 AM by sapero »

Offline Ionic Wind Support Team

  • Team Member
  • Hero Member
  • *****
  • Posts: 5759
    • Ionic Wind Software
Re: CObjectFile - create .obj files
« Reply #1 on: March 27, 2006, 10:31:50 AM »
Very interesting. 
Ionic Wind Support Team

Offline sapero

  • Senior Developer
  • Hero Member
  • *****
  • Posts: 1291
Re: CObjectFile - create .obj files
« Reply #2 on: October 31, 2010, 11:39:57 AM »
This is an application I used for the "sdkincludes" static library, for creating missing (from other static libraries) guids as small object files. This program uses the above, modified CObjectFile class (instead COFF_* custom structures, it uses the predefined structures from winnt header).

Changes in the CObjectFile class:
Code: [Select]
COFF_OBJHEADER -> IMAGE_FILE_HEADER
COFF_SECTIONTABLE -> IMAGE_SECTION_HEADER
COFF_SYMBOLTABLE -> IMAGE_SYMBOL

All you need is to enter guid name, raw data in one of four acceptable formats, and hit Save. It will create a object file with the same name as guid name. When you are finished, hit "Create static library" to merge all the object files into single static library.
In the included .ini file you need to specify which external tool you want to use for static libraries. There are 3 command line examples for link.exe, polib.exe and ar.exe.

The external tool is executed with redirected standard output stream to a file

You can drop guid name and guid data to edit controls (CDropTarget class). The "save to" edit control implements auto completion with customized IEnumString implementation - suggested are only directories (CEnumDirs class).
Default flags for auto completion are: ACO_AUTOSUGGEST and ACO_UPDOWNKEYDROPSLIST (autosuggest drop-down list + UP ARROW and DOWN ARROW keys displays the autosuggest drop-down list).

Added visual information "invalid guid data" - the edit control will be red.
Fixed a bug in guid parser: only first four hex numbers were parsed.
Added guid format without brackets.
« Last Edit: November 01, 2010, 01:40:46 AM by sapero »