How to create NTFS File links Programmatically.

21 04 2008


Unix guys don’t need an introduction about file links, because its one of the beginner Unix skills – how to create a file link. But usually in windows arena, file links may be the least discussed one among beginners. In simple words, file links are – one Physical file in disk but with different file names. All the file names points to the same file. There are a number of usages for file links.

  • Hide the master file from a bunch of naughty users.
  • You can assign different access rights for different users by creating file links for the same file.( each link have different permissions.)
  • To keep the filename constant and you can change the mapping to another file.
  • Etc etc… it goes on.


So how can i create a link for a file? You can use the api – CreateHardLink(). See the sample code snippet below.

CreateHardLink( _T(“c:\\masterfile.dat”),    // Source File
                _T(“c:\\LinkToMaster.dat”),  // Link name
                NULL );    // Security attributes


You can use DeleteFile() to delete the created link.


Targeted Audience – Beginners.





Use throw; carefully. Or else, Unhandled exception will be the result.

20 04 2008


Usually throw; is used to rethrow the exception object. But you should be careful. If you call throw; where there is no exception object in the context, then it will result an un-handled exception and abnormal program termination. The interesting part is that, even catch(…) cannot catch such exceptions.


See the sample code snippet below.

try
{
    throw;
}
catch( ... )
{
}

So take care next time.


Targeted Audience – Intermedite.





How to find the source filename and line no. from memory pointer in debug version.

19 04 2008


It will be nice, if its possible to find out the source filename and line number where the pointer is allocated by just using the memory pointer itself. Yes its possible! But only in debug version.


When you call new, the c runtime library allocates the memory and returns the pointer. But infront of the given pointer, one CRT MemoryBlock Header is secretly kept in debug version. see the declarations of Debug MemoryBlock header below.

typedef struct _CrtMemBlockHeader
{
struct _CrtMemBlockHeader * pBlockHeaderNext;
struct _CrtMemBlockHeader * pBlockHeaderPrev;
char *                      szFileName;
int                         nLine;
size_t                      nDataSize;
int                         nBlockUse;
long                        lRequest;
unsigned char               gap[nNoMansLandSize];
} _CrtMemBlockHeader;

In this header, several information about the allocated memory block is available – such as size of memory block, source filename and line no. where the memory is allocated, whether the memory block currently in use etc etc.


From the pointer, access the MemoryBlock header. Then all these informations will be available. See the code snippet below.

// decleration of MemoryBlock header from CRT Source.
#define nNoMansLandSize 4
typedef struct _CrtMemBlockHeader
{
struct _CrtMemBlockHeader * pBlockHeaderNext;
struct _CrtMemBlockHeader * pBlockHeaderPrev;
char *                      szFileName;
int                         nLine;
size_t                      nDataSize;
int                         nBlockUse;
long                        lRequest;
unsigned char               gap[nNoMansLandSize];
} _CrtMemBlockHeader;

...

// Allocate some memory.
float* pFloat = new float[100];

// Get the memory block header.
_CrtMemBlockHeader* pMemoryBlockHeader =
    reinterpret_cast<_CrtMemBlockHeader*>( pFloat );
--pMemoryBlockHeader;

// Source File and location where the memory is allocated.
CString csSourceFileName = pMemoryBlockHeader->szFileName;
DWORD dwLineNumber = pMemoryBlockHeader->nLine;


The memory allocation is different in debug and release. isn’t it? 😉


Targeted Audience – Advanced.





How to update bulk amount of data to GUI controls without flicker.

19 04 2008


Usually for Listbox and Tree control, may be you need to add and delete thousands of entries. While doing so, its obvious that the control will flicker. It might be annoying to the user. So how can you avoid it?


You can use the api – LockWindowUpdate() and UnlockWindowUpdate() for remove the flicker while updating the UI. If a window is locked by calling LockWindowUpdate(), the the further call for getting the device context will return one with empty visible region. When you call UnlockWindowUpdate(), system invalidates the area and will send WM_PAINT. The WM_PAINT will be send only if some drawing is done to the window after locking.

You can download sample from here, which shows the difference.

See sample code snippet below.

// Lock the EditBox.
m_EditBox.LockWindowUpdate();

// Add any number of strings to it.
for( DWORD Index = 0; Index < 5000; ++Index )
{
    CString csMessage;
    csMessage.Format( _T("Item %d"), Index );

    m_EditBox.AddString( csMessage );
}

// After updating, unlock it.
m_EditBox.UnlockWindowUpdate();


Please note that, only one window can be locked at a time.


Targeted Audience – Beginners.





How to locate the source code which pops the error message – More easily.

17 04 2008


While debugging huge code bases, unexpectedly some error messages can be popped up. Most probably we might be seeing it for the first time and don’t have any idea, from which location of the code base, the error message get fired. How to locate it easily?


Just follow the steps –

1) Start the project by F5.
2) Do the steps to make the error messagebox to be shown. Now the error message will be shown.
3) Now instead of clicking of in the error message, take debugger and click menu, Debug -> Break.
4) Now take Debug -> Threads to see the threads running in your application.
5) You can see one of your thread, which is paused in a messagebox showing routine.
6) Select that thread and click SetFocus, to focus that thread.
7) Now take the Call Stack by Alt+7 and iterate through it from top to bottom.
8 ) You see one familiar function? Yes! its the one which pops the error message. Now go and fix the bug 😉


You can also put a breakpoint by finding the memory address of the functions that can be used for showing error messages. But, if the application uses some custom dialogs, then you’ve to put more effort. This method is the handy one with least headaches. Try it!


Targeted Audience – Beginners.





How to check whether current user have administrator privilege?

16 04 2008


Some applications need special administrator privilege to function. Several application won’t even start if you don’t have administrator privilege. They just pops an error and exit. So, how to check whether the current user have admin privilege or not?


You can use the function – CheckTokenMembership(). See the code snippet below. Its modified and taken from MSDN.

SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup;
// Initialize SID.
if( !AllocateAndInitializeSid( &NtAuthority,
                               2,
                               SECURITY_BUILTIN_DOMAIN_RID,
                               DOMAIN_ALIAS_RID_ADMINS,
                               0, 0, 0, 0, 0, 0,
                               &AdministratorsGroup))
{
    // Initializing SID Failed.
    return false;
}
// Check whether the token is present in admin group.
BOOL IsInAdminGroup = FALSE;
if( !CheckTokenMembership( NULL,
                           AdministratorsGroup,
                           &IsInAdminGroup ))
{
    // Error occurred.
    IsInAdminGroup = FALSE;
}
// Free SID and return.
FreeSid(AdministratorsGroup);
return IsInAdminGroup;


Targeted Audience – Intermediate.





How to enable Auto Completion for Editboxes?

15 04 2008


In windows, we experience auto completion in several places such as URL auto completion in Internet Explorer address bar, File path auto completion in Run dialog etc. You can enable auto completion in editboxes or comboboxes of your application too.


Use the shell function – SHAutoComplete() to enable the auto completion feature for any edit boxes. Please see the following code snippet for how to use it.

#include "objbase.h"
#include "Shlwapi.h"

...

// Initialize COM.
::CoInitialize(0);

// Get the window handle.
// For time being, i took it from a ctrl variable.
HWND hEditWnd = m_EditCtrl.GetSafeHwnd();

// Enable Auto completion.
::SHAutoComplete( hEditWnd, SHACF_DEFAULT );


Both File path and URL auto completion will be enabled by default. If you want any one of these, just use – SHACF_FILESYSTEM or SHACF_URLALL appropriately. Have a look at MSDN for other useful flags.

Don’t forget to add library – Shlwapi.lib to your project settings.


Targeted Audience – Beginners.





Name Mangling – How to Undecorate a decorated C++ function name.

14 04 2008


For generating unique function names C++ decorates the function names to wired form. This is best known as Name Mangling. You can see sample of decorated function names by using dependency walker. Open any DLL in dependency walker and in the exported section, most probably you can see a list of decorated function names.


So, if you want to see the real function prototype of that decorated function name, what to do? Just use, UnDecorateSymbolName() function. Please see the following code block.

// Buffer for undecorating Function Name.
TCHAR tchUnDecoratedName[ 512 ];

// The Decorated function Name.
TCHAR tchDecoratedName[] =
_T( "?classCDataPathProperty@CDataPathProperty@@2UCRuntimeClass@@B" );

if( UnDecorateSymbolName( tchDecoratedName,     // Decorated Name.
                          tchUnDecoratedName,   // UnDecorated Name.
                          512,                  // Buffer size.
                          UNDNAME_COMPLETE ))   // Flags.
{
    // Display the undecorated function name.
    CString csUndecoratedName( tchUnDecoratedName );
    AfxMessageBox( csUndecoratedName );
}


Don’t forget to include the header file – “Dbghelp.h” and library file – “Dbghelp.lib“.


Targeted Audience – Intermediate.





Do you know who named C++?

14 04 2008


Do you know who named C++? Its Stroustrup who designed and created C++. But the earlier name was “C with Classes”. The name “C++” is suggested by another guy – Rick Mascitti. Read more at Stroustrup’s home page – http://www.research.att.com/~bs/bs_faq.html#name


Targeted Audiance – Everyone who wish to hear stories.





WM_COPYDATA can be used as simple IPC mechanism.

12 04 2008


Sending and receiving data between processes are one of the greatest headaches that we face. For that many mechanisms are there – such as COM, Sockets, but a bit complicated… There is comparatively simple mechanism for doing the same. i.e. WM_COPYDATA window message.


For IPC communication between two processes, you just need a hidden window created in each and by using the window handle in target process you can send data to it. For sending data via WM_COPYDATA, the following are requirements.

WPARAM – Handle of window in target process.
LPARAM – Pointer to COPYDATASTRUCT which contains data to be exported.

Please see the following code block about how to use it.

void CMyDialog::SendData( HWND hTargetWindow_i,
void* pData_i,
DWORD dwSize_i )
{
// structure holding data information.
COPYDATASTRUCT stCopyData = { 0 };
stCopyData.lpData = pData_i;
stCopyData.dwData = dwSize_i;

// Send the data.
SendMessage( WM_COPYDATA,
(UINT) hTargetWindow_i,
(ULONG) &stCopyData );
}

In the receiving Window, if you are using MFC, you need to handle the WM_COPYDATA message by adding message handle using ON_WM_COPYDATA() and handler function with proto –

afx_msg BOOL OnCopyData( CWnd* pWnd,
COPYDATASTRUCT* pCopyDataStruct );


Targeted Audience _ intermediate.