_chdir() pitfall – error while opening file.

4 10 2008


I still remember that bug! Because it grabbed my two days and delayed the delivery. Well, the story goes like this – It was during late summer of 2004. I was working in a DVD writer project. Internally we were using a third party DVD writer library named BHA Gold. Well, my project was a wrapper library for the BHA Gold library.

Well, the bug was this – There is a config file in my project, which exist in the same folder, together with exe. Before writing DVD, I’ve to read some settings from the config file. But the bug is this. During startup, I could open the file. But if I write one DVD using BHA gold, then when i tried to open the same file once again, it shows error!


At last its been found that the culprit is the api – _chdir(). The DVD writing library was calling this api internally to prepare the directory tree, and once this api is called, the default directory will be changed to the specified directory and during next time, while opening the setting file, it shows an error that “file not found”! Since the setting file does not exist in the new default directory.


Well, in such cases you could use the api – SetCurrentDirectory(). See the code snippet to set the current directory as exe’s folder path.

#include "Shlwapi.h"
...
// Get the full path of current exe file.
TCHAR FilePath[MAX_PATH] = { 0 };
GetModuleFileName( 0, FilePath, MAX_PATH );

// Strip the exe filename from path and get folder name.
PathRemoveFileSpec( FilePath );    

// Set the current working directory.
SetCurrentDirectory( FilePath );


Don’t forget to add Shlwapi.lib to project settings. 😉


Targeted Audience – Advanced.

Advertisements




How to parse the parent directory from a given path – More easily?

6 08 2008


Yesterday one of my friend called me to solve the mystery behind his crash! When i checked the code, i saw a couple of string operations by pointers, memory allocations, memset All evils under one hood. 🙂 Actually the memset caused the crash which writes beyond the buffer and corrupt other stack objects.

But suddenly i noticed one thing – what he is trying to do? He have a path and he wants to get the parent path. E.g. If his path is “C:\Application\Config”, then he want to get – “C:\Application” the just parent path. Well, the guy brushed up old string lessons and handled everything by himself which resulted in crash. I reviled him a secret api to do the stuff painlessly. Mmmm… I can tell that secret to you too…


The api is – PathRemoveFileSpec(). You can use it to remove the last directory or filename from the given path. Have a look at the code snippet.

#include "Shlwapi.h"
...
// Main path.
TCHAR pBinPath[] = _T("C:\\MyApplication\\bin");

// Get the parent path.
PathRemoveFileSpec( pBinPath );

// Now the pBinPath contains - "C:\\MyApplication"


Don’t forget to add Shlwapi.lib to project settings. 😉


Targeted Audience – Beginners.





How to check whether a file exists of not?

3 07 2008


While reading configuration file, while reading some setting file, every where we’ve to check whether the file exists or not before opening and starts reading. The simple technique is to open the file by using file apis or to search for the file by using FindFirstFile(). Or is there any simple api to do so?


You can use the api – PathFileExists(). Check the following code snippet.

#include "shlwapi.h"
...
// File path.
CString csFile = _T( "C:\\Autumn Leaves.jpg");

if( PathFileExists( csFile ))
{
    // Yes! the file exists.
}


Don’t forget to add shlwapi.lib to your project settings. 😉


Targeted Audience – Beginners.





How to generate the hash key of given data?

27 06 2008

Hashes are everywhere. Hash is small key generated from a bulk chunk of data. The hashes are useful in many ways. They are used for table lookups and data comparison. Yes! As you think now, hash table is one among them which utilizes hashes for high speed lookups. Well, thats a good, But how to generate the hash of a chunk of data?


You can use the function – HashData(). See the following code snippet.

#include "Shlwapi.h"
...
// Buffer for hash Key.
const int MAX_HASH_LEN = 256;
BYTE Hash[MAX_HASH_LEN] = {0};

// Chunk of Data.
char* pData = "Hello World";

// Generate Hash Key.
HashData( (LPBYTE) pData,
          strlen( pData),
          Hash,
          MAX_HASH_LEN );

Do you know that in real world, Hash means – “Chop and Mix”. Have a look at Wiki –
http://en.wikipedia.org/wiki/Hash_function#Origins_of_the_term

BTW, Don’t forget to add Shlwapi.lib to project settings. 🙂


Targeted Audience – Beginners.





How to find the application associated with particular file extension.

30 05 2008


Did you ever noticed that, While starting up some media player applications, they says that – “Some of its proprietary file formats are not associated with it and do you want to associate now?”. How these application are checking the associated application of particular filetype?


For a given file extension, you can find the executable associated with it by calling the api – AssocQueryString(). See the sample code snippet below.

#include "Shlwapi.h"
...
DWORD dwSize = MAX_PATH;
TCHAR tchApplicationPath[ MAX_PATH ] = { 0 };
HRESULT hr = AssocQueryString( 0,
                               ASSOCSTR_EXECUTABLE,
                               _T( ".mp3" ),
                               _T( "open" ),
                              tchApplicationPath,
                              &dwSize );

if( FAILED( hr ))
{
    // Failed to get the associated application.
}


So next time while starting, check whether your file formats are associated with your appliaction itself. 😉 BTW, don’t forget to add Shlwapi.lib to your project settings.


Targeted Audience – Beginners.





Convert colors in RGB to HLS and vice versa.

22 05 2008


RGB doesn’t need and introduction and If you are experienced in adobe photoshop, then you might be already familiar with HLS too.

RGB
All of us know about RGB. RGB is a color space in which, colors are represented by Red, Green and Blue components. Each component can vary from 0-255 in value. See the RGB color space below. (Thanks to MSDN for the pic)

HLS
HLS is also a Color space similar to RGB. But instead of red, green and blue components, HLS contain Hue, Luminance & Saturation components. Its a color space in which the Hue, saturation and luminance of a color can be separated and modified. See the HLS color space below.( Thanks to Wiki for the pic. )


Well, how can you convert RGB color to HLS and vice versa? You can use the api’s – ColorRGBToHLS() and ColorHLSToRGB(). See the sample code snippet below.

#include "Shlwapi.h"
...
// Red color in RGB
COLORREF RgbColor = RGB( 255, 0, 0 );

// Convert to HLS Color space
WORD Hue = 0;
WORD Luminance = 0;
WORD Saturation = 100;
ColorRGBToHLS( RgbColor, &Hue, &Luminance, &Saturation );

// Its converted to Hue, Luminance and Saturation.
// You can adjust the parameters according to your wish.

// Now convert back to RGB.
RgbColor = ColorHLSToRGB( Hue, Luminance, Saturation );


You can generate a wide variety of effects by adjusting HLS parameters which cannot be done by using RGB. Designers always use these HLS components for generating creative images. Take Photoshop and have a try!

BTW, don’t forget to add Shlwapi.lib to project settings.


Targeted Audience – Intermediate.





Format Size in bytes to more human readable size.

21 05 2008


In several situation we’ve to convert bytes into more readable units such as KB’s or MB’s or in GB’s. For instance, you you want to display the file size of certain files, of course you can display in bytes. But it make more readable to user if its displayed in much higher units. So how can we convert bytes into more human readable size?


You can use the function – StrFormatByteSize(). See the following code snippet. In the code, the size of the executable file is read and converted to readable size.

#include "Shlwapi.h"
...
// Get the current filename.
TCHAR szFileName[MAX_PATH];
GetModuleFileName( AfxGetInstanceHandle(),
                   szFileName,
                   MAX_PATH );

// Open the file.
CFile CurrentFile;
CurrentFile.Open( szFileName, CFile::modeRead );

// Get the file size.
DWORD FileSize = 0;
FileSize = GetFileSize( HANDLE(CurrentFile.m_hFile),
                        0 );

// Now format the size in bytes to readable string.
const int MAX_FILE_SIZE_BUFFER = 255;
TCHAR szFileSize[MAX_FILE_SIZE_BUFFER];
StrFormatByteSize( FileSize,
                   szFileSize,
                   MAX_FILE_SIZE_BUFFER );

// The szFileSize contains converted size.


For converting byte size in DWORD, you just call StrFormatByteSize(). But for converting size in LONGLONG value, you’ve to call the Unicode version – StrFormatByteSizeW() explicitly.

BTW, don’t forget to specify Shlwapi.lib to your project settings.


Targeted Audience – Beginners.