Jump to content

  • Log In with Google      Sign In   
  • Create Account

Journal #259850

Opera 9 w000000t

Posted by , 20 June 2006 - - - - - - · 272 views

Opera 9: Awesomness. The killer feature for me has got to be the widgets -- that's the only thing I missed when I moved from Firefox to Opera.


Damn

Posted by , 14 April 2006 - - - - - - · 299 views

I hate PHP. Manual installation isn't working. The windows installer isn't working. Now I have to keep mucking with this **** until I find out why it doesn't do the God-damned job it's supposed to do, and I've wasted all my day already.

And MySQL too. Damn it. The retarded thing doesn't work out of the God-damned virtual box on a God-damned 64-bit Windows. It fails near damn silently. You have to muck around. Always.

And the God-damned MySQL Query browser is one retarded piece of uninspired goo. The son of a gun allows you to open SQL query files, typically containing HUNDREDS AND THOUSANDS of SQL statements, but allows you to execute them only ONE BY ONE. By moving your God-damned cursor over the God-damned statement line till it gets white and pressing the God-damned Execute button. And then it displays some God-damned useless one-line message in the freaking status bar so that it's near damn unreadable. And it doesn't display no God-damned progress dialogs or bars or any damn thing throughout the LONG FREAKING TIMES it takes to do any God-damned thing. I hate it.

And then you have freaking Samsung monitors that are junk and keep flickering like crazy even though they're supposed to be running at 85 damn HZ. I hate Samsung.

So yeah, DAMN.


VBE fun, #2

Posted by , 26 March 2006 - - - - - - · 250 views

I spent the whole day working on the English glyphs. I wasn't happy with the ugly look in the previous entry, so I took a screenshot of an anti-aliased font, zoomed in, and started a pixel-by-pixel struggle of epic proportions, crafting the glyphs by hand, in C. I could've probably written a program to do it, but I sometimes like to brute-force my way through things (especially when I know it's going to take less than a day). Here's how it looks like now:



Each glyph is a 14x8 array of uint8s. Each element takes a value from 0 to 9, where 0 represents the background color and 9 represents the foreground (text) color. The renderer then converts this number to a a floating point value [0, 1] and uses it for blending. The only downside to this so far is that the glyph representations are no longer clear in the code:


[snip]
// 35 - '#'
{
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 8, 5, 4, 9, 0},
{0, 0, 0, 9, 4, 5, 8, 0},
{0, 0, 4, 8, 0, 7, 7, 0},
{4, 9, 9, 9, 9, 9, 9, 9},
{0, 0, 7, 5, 0, 9, 4, 0},
{0, 0, 9, 0, 4, 8, 0, 0},
{9, 9, 9, 9, 9, 9, 9, 5},
{0, 6, 7, 0, 8, 4, 0, 0},
{0, 7, 6, 3, 9, 3, 0, 0},
{0, 9, 4, 5, 8, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0}
},
// 36 - '$'
{
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 9, 0, 0, 0},
{0, 4, 7, 9, 9, 9, 7, 4},
{0, 8, 5, 0, 9, 0, 4, 8},
{0, 9, 4, 0, 9, 0, 0, 0},
{0, 5, 8, 7, 9, 4, 0, 0},
{0, 0, 4, 5, 9, 5, 8, 5},
{0, 0, 0, 0, 9, 0, 0, 9},
{0, 8, 4, 0, 9, 0, 5, 8},
{0, 4, 7, 9, 9, 9, 7, 4},
{0, 0, 0, 0, 9, 0, 0, 0},
{0, 0, 0, 0, 9, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0}
},
[/snip]



Now, I really have one thing to say before going off to sleep: Rawrrrrrrrrrrrrrrrrrrrrrrrr.


VBE fun

Posted by , 25 March 2006 - - - - - - · 247 views

I was too tired tonight to work on anything serious (e.g. message passing), so I decided to spend some time on VBE (VGA Bios Extensions). I had already downloaded, built and installed VBE GRUB to the disk image, so all that's left was to write the actual graphics code.

VBE exposes 3 functional interfaces, one through BIOS calls (via INT 10), and 2 protected mode interfaces (VBE 2 and 3 interfaces). Unfortunately, the protected mode interfaces are:
1. Lame (e.g. no return values or status codes from VBE calls)
2. Not well-supported on graphics cards
3. Not supported by bochs

So, to properly write a VBE driver one would need to:
1. Keep switching from protected-mode to real-mode and back.
or
2. Run a v8086 task to handle all this.

#1 is obviously not a real option. #2 is possible, except that doing v8086 support isn't really a priority right now. So I just settled down on accepting whatever mode we're booted into, using the information provided by the boot-loader.

The most important info passed by the boot-loader is the linear frame buffer pointer (essentially a pointer to memory-mapped display video memory) and mode information; width, height and bpp among others. With this, I set to create a simple graphics library for bidirectional text rendering (remember: Arabic support is a top priority). And of course, I started with English, since it's much easier.

For now, we're using very basic bitmap fonts. The glyphs are stored statically in the source, until we get the file system and floppy disk drivers complete and stable enough (Don't blame me! I'm not the one working on these). This amounts to the following uber-ugliness:
	uint8 en_glyphs[127 - 32][8][10] =
{
// 32 - ' '
{
".........",
".........",
".........",
".........",
".........",
".........",
".........",
".........",
},

[snip]

// 48 - '0'
{
".........",
"...###...",
"..#...#..",
".#.....#.",
".#.....#.",
".#.....#.",
"..#...#..",
"...###...",
},
// 49 - '1'
{
".........",
"...##....",
"..#.#....",
"....#....",
"....#....",
"....#....",
"....#....",
"....#....",
},
// 50 - '2'
{
".........",
"..####...",
".#....#..",
"......#..",
".....#...",
"...#.....",
"..#......",
"..#####..",
},
// 51 - '3'
{
".........",
"..###....",
".#...#...",
"......#..",
"....##...",
"......#..",
".#...#...",
"..###....",
},
// 52 - '4'
{
".........",
"....#....",
"...##....",
"..#.#....",
".#..#....",
".######..",
"....#....",
"....#....",
},
// 53 - '5'
{
".........",
"..######.",
"..#......",
"..#####..",
".......#.",
".......#.",
".#....#..",
"..####...",
},
// 54 - '6'
{
".........",
"...####..",
"..#......",
"..#......",
"..#.###..",
"..##...#.",
"..#....#.",
"...####..",
},
// 55 - '7'
{
".........",
".#######.",
"......#..",
".....#...",
"....#....",
"...#.....",
"..#......",
".#.......",
},
// 56 - '8'
{
".........",
"..#####..",
".#.....#.",
".#.....#.",
"..#####..",
".#.....#.",
".#.....#.",
"..#####..",
},
// 57 - '9'
{
".........",
".........",
".........",
".........",
".........",
".........",
".........",
".........",
},

[snip]

// 65 - 'A'
{
".........",
"...##....",
"..#..#...",
"..#..#...",
".#....#..",
".######..",
"#......#.",
"#......#.",
},
// 66 - 'B'
{
".........",
".#####...",
".#....#..",
".#....#..",
".#####...",
".#....#..",
".#....#..",
".#####...",
},
// 67 - 'C'
{
".........",
".######..",
"#......#.",
"#........",
"#........",
"#........",
"#......#.",
".######..",
},
// 68 - 'D'
{
".........",
"###......",
"#..##....",
"#....#...",
"#.....#..",
"#....#...",
"#..##....",
"###......",
},
// 69 - 'E'
{
".........",
"########.",
"#........",
"#........",
"########.",
"#........",
"#........",
"########.",
},
// 70 - 'F'
{
".........",
"########.",
"#........",
"#........",
"########.",
"#........",
"#........",
"#........",
},

[snip]

// 90 - 'Z'
{
".........",
".#######.",
"......#..",
".....#...",
"....#....",
"...#.....",
"..#......",
".#######.",
},

[snip]

// 126 - '~'
{
".........",
".........",
".........",
".........",
".........",
".........",
".........",
".........",
},
};




The 'templates' are auto-generated; the comment with the ASCII code and display symbol, and the dot matrix. The generator is a small C++ program. I then fill the parts to be displayed with any non-dot non-zero symbol. As you can see, it's not complete yet - I've just worked on it until I was bored out of my skull, and then ran a simple test:



So yeah, it works, although the font looks so freaking ugly. Ideally, FreeType should be used for the fonts, but that's a bit too much into the future.


Some people have to be shot

Posted by , 22 March 2006 - - - - - - · 244 views

A long time ago, I thought installing InstallShield update manager would be a good idea. For a variety of reasons, it wasn't. I couldn't find a way to uninstall it, though. No start menu entry, no Add/Remove Programs entry, no way to do it from the application itself. In the past, I'd look for a way quickly, not find one, and then forget about it.

Today, I did a little google search on uninstalling the retarded beast. And guess what? Howto: Uninstall update manager. You need to download a freaking uninstaller that's 2.4 MBs.

Wow.

Way to go for a company whose business is the mechanics of user-friendly application installation and uninstallation.

Smacktards.


French, #1

Posted by , 20 March 2006 - - - - - - · 351 views

So, I decided I sould revive my m4d french sk1llz. I've (lightly) studied French in school for approximately 7 years, but - unfortunately - I didn't put that knowledge to good use. The result is that I can now read and understand French if it's not heavy on the vocabulary, but I'm totally unable to write or compose anything in French. And of course, I can't decipher what native French speakers babble at all. Talk about speaking at light speed.

I'm using this WikiBook as a starting refresher. I still haven't set up a schedule for myself, but I'm aiming at writing at least two French journal entries per month. And by French journal entry, I mean something like "Je suis Egyptien". Yeah, I'm taking it easy in the beginning.

And I'm not only writing French journal entries, but I've hunted for some technology oriented French forums and am going to lurk there for a while. My initial attempts at finding such websites were rather unsuccessful. However, once I found the correct keywords, I stumbled upon this. C'est très formidable!

Unfortunately, not all is well. I'm currently facing 2 issues:

First, being armed with not-so-powerful dictionaries might prove to be troublesome. For example, I wanted to know what the French equivalent of "Fantastic" was, expecting it to be Fantastique (The English word sounds way too French that it must've been borrowed). The dictionary suggested "endiablé".

Suspicious.

Consulting a printed French-Arabic dictionary I have, "endiablé" is supposed to mean "Satanic", "Diabolic" or "Very fast" (Wha?). Consulting a high-school level French-French dictionary I have (the ultimate source!), it says "Trés rapide". [dead]

If any kind french readers can drop me a link to a good online French-French or French-English dictionary, I'd be very grateful. So grateful, in fact, that I'd dedicate my next French entry entirely to praising you. Think How Washu Is Better style, except in French. And a bit short. As in a couple of lines or something. C'est une offre que tu ne peux pas réfuser! (OMG, did I get that right? It took me ages to remember verb pouvoir)

Second, the French keyboard layout is rather weird. At least it is on Ubuntu linux. The 'q' and 'a' are swapped, for some reason. Numbers are now entered via Shift+Key, whereas Key inserts a character or symbol. Is this the way you guys do things normally, or am I missing something?

Anyway, issues aside, let me share with you the astounding knowledge I have gathered so far. Some essential C-related terminolgy:

& -> Esperluette. Frankly, this is way cooler than "ampersand"
* -> Asterisque. I cannot help but adore the cuteness of the way this is pronounced
\ -> Barre oblique inverse. Not cool
[ ] -> Crochets. Easy to remember. Similar to "Crotch", isn't it? Thankfully, it has different pronunciation
: -> Deux points.
; -> Point virgule.
, -> Virgule.
= -> égal. Umm..how do you write an uppercase 'e' with an accent? Is there even such a thing?
! -> Point d'exclamation.
> -> Supérieur à.
< -> Inférieur à.
( ) -> Parenthèses.
{ } -> Accolades.
% -> Pourcent. modulo?
# -> Dièse. Je programme en C dièse. Yay!
_ -> Soulignement.

That's it.

PS: What do you know, it looks like the French brain cells in me are waking up. I remembered a part of the following childish song:
Savez-vouz plantez les choux
a la mode a la mode
Savez-vous plantez les choux
a la mode de chez nous
[Don't remember the rest - but it had things to do with arms, elbows and feet I think. A search came up with it, though: here]

French word of the day
Pipi: Guess what this one means.
Example usage: J'ai envie de faire pipi.

Hint: Memorize the above statement, and you know you won't wet your pants if you ever get lost in France.

Exercise: Learn how to secure yourself against soiling your pants.


PS2: Just for Jack's sake. Du lait est supérieur à du Café.


Mult-tasking

Posted by , 19 March 2006 - - - - - - · 150 views

Since last Thursday, I've been debugging multi-tasking. I had kernel-space threads running fine (which is cool, by the way. Multi-threaded kernels, that is), but I could never do a successful privilege level switch (aka ring switch, from kernel-space to user-space and back). I was always getting bogus SS values when switching back from user-space to kernel-space. This SS value is retrieved from the TSS. I hex-dumped the TSS in my OS and it showed up fine. After lots of reading and re-reading of the Intel manuals, OS-dev tutorials and documents, I couldn't find out what's wrong.

I downloaded the bochs source, and began modifying it - making it print more details when the bogus SS is loaded. I found out that it's loaded with a value that's totally outside the TSS, which means it's looking at a wrong TSS. I inspected the bochs code that loads the SS from the TSS, and from that it was obvious I'd have some retarded bug with my GDT setup.

This was actually one of the very rare occasions I made use of the 'openness' of an open-source software package. Obviously it's a nice thing to have with developer-oriented tools and applications. Thank God bochs builds in under a minute. (Binutils, I'm looking at you! [grin])

Anyway, back to the bug. My TSS setup was like so:

// TSS descriptor
segment_descriptor_t& tss_descriptor = m_gdt_entries[TSS_SEGMENT_DESCRIPTOR_INDEX];
memory_set(&tss_descriptor, 0, sizeof(segment_descriptor_t));
tss_descriptor.limit_0_15 = sizeof(tss_t) - 1;
tss_descriptor.base_address_0_23 = reinterpret_cast<uint32>(&tss) & 0xFFFF;
tss_descriptor.base_address_24_31= (reinterpret_cast<uint32>(&tss) >> 24) & 0xFF;
tss_descriptor.segment_type = TSS_SEGMENT_TYPE;
tss_descriptor.ring = 0;
tss_descriptor.is_present = 1;
tss_descriptor.granularity = GRANULARITY_BYTE;




In case you haven't spotted it, the problem is in the base_address. The base_address is split into 2 fields; one is 24-bit wide, the other is 8-bit wide. I was taking only the first 16-bits when filling the first field [dead]. That meant the CPU was reading from a memory address that is significantly lower than the actual TSS address.

So yeah, now I have proper kernel-space to user-space switching and back. Yay!



Throughout this week, I intend to:
- Write thread synchronization objects
- Write basic process management code
- Write a basic system call interface
- Implement separate address spaces for different processes (I'm currently using a flat protected memory model where only accesses to out-of-physical-bounds memory addresses are intercepted).
- Move the keyboard and mouse drivers to user-space
- Write a better user-space test shell (I already have one running in kernel-space)

That's probably too much for one week, but who knows.

This is more of a reminder to myself:
Things that can make it into the next entry:
- Keyboards are not only evil, but retarded too
- I hate to admit it, but gVIM is better than I thought
- Window managers are unnecessarily heavy (e.g. gnome vs xfce)
- Rox filer is cool
- Linux distros still suck at usability and stability
- Color schemes: Black on lightyellow is awesome
- Automake and Autoconf...the day I understand what they're about is the day I die.
- CodeWarrior 9 for the PalmOS is torture
- PalmOS 5 is torture
- Palm devices are torture
- C++ is torture
- So is assembly
- I think I love and hate C++ templates in the same time.
- Long live the 'typename' keyword.
- Writing a correct generic linked list implementation is NOT as easy as one might think
- Testing it isn't easy either
- STLPort std::list tests are not as exhaustive as I thought. In fact, they're more like a joke. Unless I missed something.
- Backward compatibility sucks equally for hardware and software.
- Unit-testing OS components is hard.
- Automating the tests is even harder.
- Debugging OSes is hard too.
- Floppy disks are the most unreliable pieces of junk EVER.
- I bought a new chair.
- And a new keyboard.
- And a new mouse.
- Dual keyboard setups are cool.
- And so is "Little Fighters 2".
- D-Link middle-east routers and switches suck. Probably Ethernet adapters too. A combination of an ethernet adapter, switch, and router is bound to drive you crazy.
- Green tea is way cooler than red tea. Not sure how it compares to coffee, though.
- I think I just had a brain haemorrhage.
- Haemorrhage (also hemorrhage) is such an interesting word. It almost defies correct spelling.
- Must...stop...now...



OneNote, DInput-Hooking

Posted by , 09 February 2006 - - - - - - · 565 views

Microsoft OneNote is becoming one of the most invaluable programs I have ever used in my life. Since I started using it, it dramatically affected the way I work, the way I surf, and, in general, the way I use my computer.

Even though it provides a lot of nice features, what really hit the sweet spot with me was the ability it gives you to write 'anywhere' on a given page. This lends itself naturally to the process of design as I conceive it. I've always preferred working with pencil and paper whenever creativity or even mere thinking was involved. I've never been able to exactly pinpoint what the main difference between pencil-and-paper and Word-Processor was, until I tried OneNote.

Freedom.

Freedom to write something at the top of the page, leave it and quickly scribble something at the top-right corner of the page, get back to what I was writing, then expanding whatever I've scribbled into a box on the same page, dragging an arrow from this box to that - that sort of thing. Typical word-processor software forces you into a limited top-down flow of words, and consequently, thoughts. And I've always hated that. And I really couldn't work around that inherent limitation, no matter how I tried.

Another fine difference is the definition of what a page is. Word-processors view pages as sequential entities - they come after each other, again, top-to-bottom - and as part of one larger entity, "The Document". Which really is not true at all during the design process, as it applies to me.

When designing, the concept of cards (for lack of a better term - I'm not specifically referring to
Class-Responsibility-Collaborator (CRC) Cards
, even though they might be part of the design process) takes over. Each page is a separate entity of its own, with its own title, and it becomes desirable to have all the pages visible at the same time. And if not possible, one should be able to switch between them quickly.

Another thing that Word-processors don't have is hierarchal organization. A project consists of a number of components. Each components may yet consist of additional sub-components. And each of these has, associated with it, a number of so-called cards. And that's not really a software-specific trait. Generalizing, anything consists of a number of component things. You can choose to break it down to its components or not depending on your desired level of abstraction - and the software program had better provide you with the ability to do just that.

Finally, all this isn't very useful if you don't have the ability to properly search these collections of pages or parts of it, in an information-hunting fashion, like a search engine.

OneNote solves all that through what I consider a very elegant design:



First, the "Projects" dropdown you see is part of a tree. A tree consisting of a number of folders, subfolders, and sections. Each section contains a number of pages. The section pages are tabbed to the right of the page, in a collapsible area. When you collapse it, only the page numbers appear, instead of their titles.

A new page is quickly created by clicking the 'New page' icon (numbered 3). You can quickly switch to other pages simply by clicking their tabs.

Whenever you click on a page, you get a writing area similar to that to the top-right. The one in the top-right has the mouse hovering it, which is why it has the additional rectangular bar on-top. You can resize any such area quickly using the arrows (numbered 2 in the picture). You can move the area around by clicking anywhere in the dotted rectangle (numbered 1) and dragging. Areas resize automatically when you type in them and when there's enough space to resize.

That enough makes it a super-cool tool for me - I now have a centralized place for my design documents, technical designs, journal posts, informative posts and notes. And I can save any of them as Word documents.

But I was pleasantly surprised when I discovered that you don't have an explicit saving mechanism. It saves everything transparently. Yes, that's the closest thing to orthogonal persistence I've seen on today's systems. Mind you, I've not tested ending the Windows session abruptly to check how much information I'd lose, but it's quite enough to me that it saves everything if you switch away or shutdown Windows normally.

So, in conclusion, give it a try. Now, let me get into what I actually started writing the entry for, before going off at a tangent and kissing OneNote's boots.

The following are snippets from my notes, written during the design and implementation phases of the DirectInput hooking component. Microsoft OneNote really shined in this part. It allowed me to easily layout the scenarios before-hand, in English, then fill in the details with the needed API calls and how they were to be used.




When developing the DirectInput hooking component - and before it, the Direct3D one - the only 'real' issue was external world communication. I needed such communication in 2 situations:

Hook application determination
It had to know the name of the application to be hooked. When writing the Direct3D hook, I went with the simple solution of using the registry, and it had worked fine. When writing the input hook, I saw no need to change the way this works.

Keyboard state control
After successfully hooking the target application, we need to be able to receive key-press commands and forward them to the target application.

Therefore, IPC.

After digging for a while in the documentation, the most simple IPC methods I found were:
· Pipes
· Mail slots
· Sockets

Named pipes were the most obvious and simple solution. So I laid out the following scenarios in an English-only pass, then filled it with API references and information in the second pass, using the MSDN documentation.




Named pipes - The server side

First, a named pipe is created by the keyboard device using CreateNamedPipe. The pipe handle is stored within the keyboard device for further use. Pipe creation parameters are:
· Name: \\.\pipe\DInput-Hook
· Open Mode: In-bound
· Pipe mode: PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE
· Max instances: 1
· Out buffer size: 0
· In buffer size: 256
· Default timeout: 200
· Security attributes: null

Whenever the hooked application retrieves the keyboard state, we peek into the pipe to see if we've got any data. A peek is done using PeekNamedPipe, as follows:
· Named pipe: Pipe handle
· Buffer: null
· Buffer size: 0
· Bytes read: 0
· Total bytes available: 0
· Bytes left in this message: messageBytes

The call retrieves the number of bytes available in the message in messageBytes.

If we've got some data, we read them via ReadFile:
· Handle: Pipe handle
· Buffer: A 256 byte buffer
· Num bytes to read: messageBytes
· Num bytes read: numBytesRead
· Overlapped: null

The message consists of a string of numbers, each number representing a scan-code.

Named pipes - The client side

The application should loop endlessly, calling WaitNamedPipe until the pipe is created - this signals the target application's launch and creation of a keyboard device.

It then connects using CreateFile:
· File name: \\.\pipe\DInput-Hook
· Access: GENERIC_WRITE
· Share mode: 0
· Security attributes: null
· Disposition: OPEN_EXISTING
· Attributes: FILE_ATTRIBUTE_NORMAL
· Template file: null

It can keep forwarding messages using WriteFile:
· Handle: Pipe handle
· Buffer: The message buffer
· Num bytes to write: Message size
· Num bytes written: numWritten
· Overlapped: null

When it's done, or an error occurs, it can go ahead and close the pipe using CloseHandle.




Using the above scenarios, I quickly laid out how I want my classes (which was really simple given how simple the scenarios are)

NamedPipeServer


Operations
· Create
· Destroy
· IsDataAvailable
· Read

Attributes
· Pipe handle

NamedPipeClient


Operations
· IsServerAvailable
· Connect
· Write
· Disconnect

Attributes
· Pipe handle




DI7


And the implementation of the above design worked almost right away, hassle-free, and life was good. Until Daphyd The Bard contacted me - he was having trouble to hook a (cool) asteroids game he's been working on. Whenever his launcher loaded the hooking DLL, VB6 would fail with a "File Not Found" error. I tested it on my PC with a VB6 application, and it worked. And when I sent the generated EXE and DLL to him, it didn't.

I had Jack "OMG-FIFTY-REPLIES-PER-SECOND" Hoxely test the same sample and it worked on his PC, promptly popping up a message box saying "LOL", which was the expected behavior. And then it hit me. Both Jack and I use Visual C++ 8, so we both have the runtime installed. And guess what C++ runtime VC8 uses by default? Yep, Multi-threaded DLL runtime. Which David didn't have.

So I switched to the static runtime and the DLL loaded successfully on his computer. But it still didn't work with his game.

After loads of experimentation, debugging and hair-pulling, I discovered that his game was written using DI7. And of course I only hooked DI8 applications.

[lol]

So, I decided to support DI7 too. Initially, I thought it was going to be a minimal amount of work - a copy-n-paste job. Hook DirectInputCreate and there you go. Unfortunately, that didn't work. And Oh God, it didn't work in so many ways.

After a bit of code revision and fiddling to make sure it's not something in my code, I decided it wasn't. The application in question wasn't calling DirectInputCreate - simple as that. So I went looking for alternative ways to create the DirectInput object, and found:
1. DirectInputCreateEx
2. CoCreateInstance

I hooked both of them. And it didn't work - the application wasn't calling them either.
So now I was back at square one. How does the application go about creating a DirectInput object without these?

Then it struck me. DirectInputCreate is actually a macro that resolves to either DirectInputCreateA or DirectInputCreateW, depending on whether the code in question is compiled with the UNICODE flag. So I quickly hooked these two too, and ran the target application.

And it still didn't work.

Another time, I revised the code, did a couple of experiments, but still couldn't get it. Then It Finally Hit Me. We hook functions by simply searching for references to their container DLLs in the EXE headers and replacing their entries in the import tables with entries of our own functions in our DLL. There's no way that's going to work when you're not directly calling the functions in questions, because then you wouldn't have them listed in your headers.

Visual Basic 6 does this. It calls into dx7vb.dll and dx8vb.dll for 7 and 8, respectively. A quick look at dx8vb.dll using the pexports utility that comes with MinGW wasn't very enlightening. The only exported function that looked promising was DllGetClassObject. I hooked that but it wasn't being called.

Unfortunately, I don't have much experience when it comes to COM and all the VB-C++ interaction. I have a couple of ideas, and I might try them out later, but for now I'll move on to something else. I'm currently at a dead-end with VB-based applications.

Not so random link

Hilarious comics by our very own 'boolean'


EDIT: Made the image a clicky.






Recent Entries

Recent Comments