Saturday, September 19, 2009

EasyConfig C++ Class

Hey all, I just wanted to share with you a class I made that is kinda useful when you want to manipulate the Config files such as *.ini.

You'll see it's not hard at all to use it.

Please note that there are 2 constructors, an empty one that doesn't require any argument and another one that takes the file name.
->If you declare an object without any file name, you'll have to use the SetFileName method.

Here's an exemple :
#include "stdafx.h"
using namespace std;

int main(int argc, char* argv[])
{
ConfigFile myIni;

myIni.SetFileName("C:\\Hax.txt");

cout << myIni.ReadStringValue("LOL", "value1").c_str() << endl;

    cout << "Writing int into value2..." << endl;

    myIni.WriteValue("LOL", "value2", 1337);
    cout << myIni.ReadIntValue("LOL", "value2") << endl;

    cout << "Writing float into value3..." << endl;

    myIni.WriteValue("LOL", "value3", 3.14f);
    cout << myIni.ReadFloatValue("LOL", "value3") << endl;

    return 0;
}
WriteValue is an overloaded function that works with float, int and strings which is actually what I needed. The code launches a ConfigFileException when shit happens. For exemple :
ConfigFile myIni;

cout << myIni.ReadStringValue("LOL", "value1").c_str() << endl;
In this code, we didn't set a file name. The code will launch an exception that contains : - The file name (In this case, it's ) - And the error description To avoid unhandled exceptions :
ConfigFile myIni;

try
{
cout << myIni.ReadStringValue("LOL", "value1").c_str() << endl;
}
catch( ConfigFileException e )
{
cout << "*** EXCEPTION CAUGHT ***"<< endl;
cout << e.fileName << endl;
cout << e.errMessage<< endl;
}
I added the exceptions stuff today, so if you find anything i could add/correct, just say =) And now, the file you're all waiting for : EasyCfg.cpp
Alright, if you liked this don't forget the credits if you'd like to use it. A 'thank you' never killed anybody ;)

Using the Kernel Level Video Memory

How to use the Video Memory


Here are the ways to use the computer's video memory, I'm first going to show you how to use it from it's address.

Generally, the Video Memory Base Address is 0xB8000. When you want to draw a character, you must set 2 bytes. The first one is is the character, the second is the
attributes. Here's an exemple to understand how to print a character :
mov byte [0xB8000],'A' ;The Character Itself
mov byte [0xB8001],0xF ;Character's Attribute (0xF = 00001111)
Here's defined a black background with a white foreground :

Blinking (H) BackGround (H) Intensity (L) ForeGround (L)
0 000 1 111

The colors are in RGB format, The max value is 1, the minimum is 0
Color
Code
Black
000
Blue
001
Red
100
Green
010
Yellow
110
Purple
101
Cyan
011
White
111


Now that we know the basics, we're going to write our first string !
mov byte [0xB8000],'H'
mov byte [0xB8001],0xF
mov byte [0xB8002],'E'
mov byte [0xB8003],0xF
mov byte [0xB8004],'L'
mov byte [0xB8005],0xF
mov byte [0xB8006],'L'
mov byte [0xB8007],0xF
mov byte [0xB8008],'O'
mov byte [0xB8009],0xF
mov byte [0xB800A],' '
mov byte [0xB800B],0xF
mov byte [0xB800C],'W'
mov byte [0xB800D],0xF
mov byte [0xB800E],'O'
mov byte [0xB800F],0xF
mov byte [0xB8010],'R'
mov byte [0xB8011],0xF
mov byte [0xB8012],'L'
mov byte [0xB8013],0xF
mov byte [0xB8014],'D'
mov byte [0xB8015],0xF
mov byte [0xB8016],' '
mov byte [0xB8017],0xF
mov byte [0xB8018],'!'
mov byte [0xB8019],0xF
Example ran in VirtualBox :




But, typing all this code is odd, and we could write a DrawString function. Let's write it in C :



   #define RAMSCREEN 0xB8000       /* Video Memory */
   #define UCHAR unsigned char
   #define LPUCHAR unsigned char*
   LPUCHAR VideoMemory = (LPUCHAR)RAMSCREEN;
   int strlen(char* text)
    {
    int i = 0;
  
    while(text[i])
    i++;
  
    return i;
    }

    void print(char* text)
    {
    int i;
    int j;
    for(i = 0, j = 0; i < strlen(text); i++, j += 2)
    {
    VideoMemory[j]     =     text[i];
    }
    }
I tried to make it in ASM for you lucky people, but because I'm not a pro, it sucks a bit :


    DrawString:
    xor ebx, ebx
    xor edx, edx
    mov ebx, [ConsolePos]
    draw_start:
    mov al, [ecx]
    cmp al, 0     ; \0 char ?
    je draw_end
    cmp al, 10     ; New Line ?
    je new_line

    ;Print the char
    mov byte [0xB8000 + ebx], al
    add ebx, 2
    inc ecx

    jmp draw_start

    new_line:
    mov edx, [ConsolePos]
    add edx, 160
    mov ebx, edx
    mov [ConsolePos], ebx
    inc ecx
    jmp draw_start
   draw_end:
    ret

    C_SystemLoad     db "Loading Main Kernel...", 10, 0
  
ConsolePos         dd 0
   KernelStart:
    mov ecx, C_SystemLoad
call DrawString
   end:
jmp end

Well I hope you've learnt from this tut, This tutorial was written by me. Thanks to OSDev for their helpful forums/website ;D