i.e.: e.g.

To avoid looking foolish, it is a good idea to learn to properly use the Latin abbreviations eg and ie. Think about what they mean, does the sentence sound right when you replace them with their English meanings?

AbbrLatinEnglish
EGExempli GratiaFor Example
IEId EstThat Is
  

Use a web-browser, eg: IE, FireFox, Opera.
Use a web-browser, for example: IE, FireFox, Opera.
Use a web-browser, that is, IE, FireFox, Opera.

He ruined the project, ie, he couldn’t finish it on time.
He ruined the project, that is, he couldn’t finish it on time.
He ruined the project, for example: he couldn’t finish it on time.

It is not difficult to use them properly when you know what they mean.

Self-Viewing Data Files

This article shows one way of creating self-viewing data files. Examples of such things include self-extracting archives and self-playing videos. Self-viewing data files are executable files that put the data and the viewing program together in a nice neat little packa-ge.

This will require two programs, the player and the creator. The player will be embedded as a resource inside the creator. The creator extracts the player (aka the “stub”) and saves it as the target file, then embeds the data file in that as a resource. The player, when run will read the data file from it’s resources and display it.

To accomplish this, there will need to be a few functions that access or manipulate resources. Here are the ones required and who the onus falls on:

StepFunctionResponsible
1Insert  viewing program as   resource into creator program   You, programmer
2Extract viewing program from resource and save to file       Creator program
3Insert  data file       as   resource into viewing program   Creator program
4Extract data file       from resource and save to file/displayViewing program

The obvious way to do this is to use the native resource functions. Unfortunately, the functions for updating resources is not available for Win9x systems, only the ones for reading them are. There is a way to add the missing support by using the MSLU but that adds to the size and requires including a DLL with the program. An easy alternative is to manually handle the “resources” by injecting them in and extracting them from the stub. This is the method used in this article. We’ll break down the work into the separate programs. First the player.

The Player (stub.exe)

Step 4
The viewing application (the stub) will need to be able to extract the data from itself. The data will be located at the end of the executable, followed by the size of the data (so that we know how much data there is), and finally a signature. Here is some (surprisingly) simple code—sans error checking—to read a chunk of plain text:

void ReadResource() {
    CFile f;
    DWORD sig =0;
    LONGLONG size =0;
    CString t =_T("");
    //open itself for reading
    if (f.Open(__argv[0], CFile::modeRead)) {
        //read the last 4 bytes of the file and check if it is the signature
        f.Seek(-((LONGLONG)sizeof(sig)), f.end);
        f.Read(&sig;, sizeof(sig));
        if (sig==0x12344321) {
            //read the size
            f.Seek(-((LONGLONG)(sizeof(size)+sizeof(sig))), f.end);
            f.Read(&size;, sizeof(size));
            if (size) {
                //seek to the start of the data
                f.Seek(-((LONGLONG)(size+sizeof(size)+sizeof(sig))), f.end);
                //allocate a buffer for the data and read it
                f.Read(t.GetBufferSetLength((UINT)size), (UINT)size);
                //display the read data in the edit control
                GetDlgItem(IDC_EDIT1)->SetWindowText(t);
            }
        }
        f.Close();
    }
}

Other types of data can be read in the same manner.

The Creator (create.exe)

Step 2
We can use the same technique as above to read the stub from the end of the creator program, but here is a way to do it with the normal method of using resources (which is supported):

//search for and locate the stub resource
HRSRC shstub=FindResource(NULL, MAKEINTRESOURCE(IDR_STUB), _T("BIN"));
if (shstub) {
    //verify the size of the stub
    DWORD rs=SizeofResource(NULL, shstub);
    if (rs) {
        //load the stub resource
        HGLOBAL hstub=LoadResource(NULL, shstub);
        if (hstub) {
            //lock the stub resource to get a pointer to it's first byte
            BYTE* stub=(BYTE*)LockResource(hstub);
            if (stub) {
                //create an executable file
                CFile stubf;
                if (stubf.Open("stub.exe", CFile::modeCreate|CFile::modeWrite)) {
                    //copy the stub to the file
                    stubf.Write(stub, rs);
                    stubf.Close();
                }
                UnlockResource(hstub);
            }
        }
    }
}

Step 3
The stub is now written to the disk but is just a viewer. We have to inject the data file for it to display:

//get the data to be injected (simple edit box in this case)
UpdateData();
CString  t =::GetWindowText(GetDlgItem(IDC_EDIT1));

CFile    f;
LONGLONG size=0;
DWORD    sig =0;

//open the player file
if (f.Open("myfile.exe", CFile::modeReadWrite)) {
    //we need to check if there's already something there
    //read the last 4 bytes from the player file and check if it's a signature
    f.Seek(-((LONGLONG)sizeof(sig)), f.end);
    f.Read(&sig;, sizeof(sig));
    if (sig ==0x12344321) {
        //there's already a resource there, so we'll have to replace it
        //read the size of the existing resource
        f.Seek(-((LONGLONG)(sizeof(size)+sizeof(sig))), f.end);
        f.Read(&size;, sizeof(size));
        if (size) {
            //add the size of the size and signature
            size+=sizeof(size)+sizeof(sig);
            //truncate the file, leaving just the stub
            f.SetLength(f.GetLength()-size);
        }
    }

    //seek to the end of the file
    f.Seek(0, f.end);
    size=t.GetLength();
    //write the data file to the stub
    f.Write(t.GetBuffer(), (UINT)size);
    //write the size of the data
    f.Write(&size;, sizeof(size));
    //write the signature
    sig=0x12344321;
    f.Write(&sig;, sizeof(sig));

    f.Close();
}

Step 1
Finally, we need to insert the stub into the creator program. If you are using the resource method, then it can be added as any other resource, making sure to use type BIN and using stub.exe as the source. If you are using the manual method, then you will need to manually append stub.exe to creator.exe, add the size of stub.exe, then the signature.

Now, just compile stub.exe, then creator.exe. Run the creator program and create some data. Click the export player button, and select the filename to save. The creator will read the stub, save it to disk, and inject the data. Now run the self-contained data/viewer file. It will extract the data from itself and display it.

Note: there are a couple of drawbacks to using this method. First, while it works, it is not part of the PE format standard. Future revisions of the PE format may break this, especially with the crackdown on code execution. Another potential problem is that some virus scanners may detect the modification of an executable as suspicious activity and thus have a bad reaction, causing itchy, watery eyes and a runny nose. The virus scanner can be circumvented however, by writing the stub to a non-executable file (say myfile.bin), then renaming it after the data has been injected.

Quieter, Smoother Computer

Most computers come with fans to keep them running cool enough to avoid problems. Unfortunately, fans have moving parts, move fast, and stir air. All this results in quite a bit of noise which can cause headaches, not to mention being down right annoying. It also causes a lot of vibration which further adds to the noise, headaches, and annoyance. Some people get rid of their fans and use alternative cooling methods, however most of these are just too expensive for the regular computer user, and worse, too complicated. Good computer cases will come with rubber feet instead of the hard plastic ones that cheaper cases have. The rubber feet will absorb the vibrations instead of passing them to the desk, floor, or whatever surface the computer rests on. If your case does not have rubber feet, then you can add them if you are comfortable/able to open the case. If not (or even if your case does have rubber feet), there is a quick, easy, and cheap trick that can help to reduce vibration which will result in less noise and provide quieter, smoother computing environment.

Simply place a couple of foam-rubber mouse-pads beneath the computer. You’ve probably got a few lying around somewhere, or can easily buy a couple for under a dollar. The design does not matter, so you can get generic ones for less. The thick, foam-rubber kind work best, although even the thin rubber kinds are better than nothing. In either case, you just slip in under the computer to cushion it from the desk, making sure that the rubber side faces the computer. Even better, fold it in half (rubber side out), and you’ve got a vibration damping, noise canceling, double-cushioned, non-slip shim between the computer and the desk.

*UPDATE*
Here is a blog entry which says pretty much the same thing and includes pictures.

Tip: Smooth Mouse Scroll Wheel

Here’s a tip for those with scroll mice. Take the clicker out of the wheel. Scroll mice usually accomplish the clicking of the scroll wheel by means of a spring or metal stick that press inside the wheel. Take this out, the wheel will turn nice and smooth. It may take a little getting used to, but it will soon feel great.

Of course you should realize that the clicking serves a function: to limit the movement of the wheel. If the scroll wheel is too loose, it may spin out of control without it, but normally it won’t. In fact, in some mice, the clicker may cause unwanted scrolling, so removing the clicker will eliminated that.

(The little metal stick inside my mouse broke recently, and I panicked because it was a fairly new, expensive mouse, but before I knew it I was hooked—pun intended. I never want to use a clicker again.)

Outlook Express Folder Compaction Error

If you get the following message for FOLDERS.DBX when trying to “compact all folders” in Outlook Express

The folder is currently in use by Outlook Express or by another application.

there is a simple solution. The error message is deceptive since the actual cause has nothing to do with being in use. The problem occurs when you try to compact all folders and not all folders are actually present on disk. This can happen if a .DBX file got deleted somehow (for example if you decided to save some space by deleting the .DBX files of empty folders.) When OE tries to compact, it checks the folders.dbx file to see what .DBX files to expect, and when it can’t find one, it complains with the inaccurate message above.

The fix is simple, just replace or recreate the files. The easiest way to do this is to simply open the missing folders in OE because it will automatically create a .DBX file if one does not exist.

If you do not know which ones are missing, you can click on “Local Folders”, press the * key on the keypad to expand all branches, then click on each and every folder—you could also use the Down key instead of clicking, but then you have to wait a second on each folder for OE to open them, clicking opens them instantaneously.

After you’ve ensured that all .DBX files exist, you can successfully compact all folders.