Click here to Skip to main content
15,893,663 members
Articles / Programming Languages / C++

Registry Symbolic Links

Rate me:
Please Sign up or sign in to vote.
4.75/5 (14 votes)
21 Oct 2005CPOL9 min read 69.2K   2K   30  
An article on creating and using registry symbolic links.
static char *rcsid = "$Id: linkcreatDlg.cpp,v 1.5 2005/10/16 12:19:49 cvs Exp $";
/*
*
* $RCSfile: linkcreatDlg.cpp,v $
* $Source: /cvs/rgsymlnk/linkcreat/linkcreatDlg.cpp,v $
* $Author: cvs $
* $Revision: 1.5 $
* $Date: 2005/10/16 12:19:49 $
* $State: Exp $
* Copyright (c) Stefan Kuhr
*
*
*
* $Log: linkcreatDlg.cpp,v $
* Revision 1.5  2005/10/16 12:19:49  cvs
* Added SetSymLink flags
*
* Revision 1.4  2005/10/16 11:48:41  cvs
* Simplified and consolidated error output
* 
*/

// linkcreatDlg.cpp : Implementierungsdatei
//

#include "stdafx.h"
#include <afxpriv.h>
#include "linkcreat.h"
#include "linkcreatDlg.h"
#include "../rgsymlnk.h"

/// 
/// local macros:
/// 
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define REG_KEYS _T("Keys")
#define REG_LINK_TARGET _T("Target")
#define REG_LINK_SOURCE _T("Source")
#define REG_LINK_PREDEFKEY _T("Predef")

/////////////////////////////////////////////////////////////////////////////
// CLinkcreatDlg Dialogfeld

CLinkcreatDlg::CLinkcreatDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CLinkcreatDlg::IDD, pParent),m_hLinkKey(NULL)
{
	//{{AFX_DATA_INIT(CLinkcreatDlg)
		// HINWEIS: Der Klassenassistent f�gt hier Member-Initialisierung ein
	//}}AFX_DATA_INIT
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CLinkcreatDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CLinkcreatDlg)
	DDX_Control(pDX, IDC_CMB_PREDEF, m_cmbPredefRegHandles);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CLinkcreatDlg, CDialog)
	//{{AFX_MSG_MAP(CLinkcreatDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_CREATE_LINK_TARGET, OnBtnCreateLinkTarget)
	ON_BN_CLICKED(IDC_BTN_CREATE_SRC_KEY, OnBtnCreateSrcKey)
	ON_BN_CLICKED(IDC_BTN_DELETE_LINK_TARGET, OnBtnDeleteLinkTarget)
	ON_BN_CLICKED(IDC_BTN_DELETE_SRC_KEY, OnBtnDeleteSrcKey)
	ON_BN_CLICKED(IDC_BTN_LINK_TO_SOURCE, OnBtnLinkToSource)
	ON_WM_DESTROY()
	ON_MESSAGE(WM_KICKIDLE, OnKickIdle)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLinkcreatDlg Nachrichten-Handler


#define dimof(a) (sizeof(a)/sizeof(a[0]))

const LPCTSTR g_szHandles[] = 
{
    _T("HKEY_LOCAL_MACHINE"), 
    _T("HKEY_CURRENT_USER"), 
    _T("HKEY_USERS"), 
    _T("HKEY_CLASSES_ROOT")
};

const HKEY g_hkHandles[] = 
{
    HKEY_LOCAL_MACHINE, 
    HKEY_CURRENT_USER, 
    HKEY_USERS, 
    HKEY_CLASSES_ROOT
};



BOOL CLinkcreatDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	SetIcon(m_hIcon, TRUE);
	SetIcon(m_hIcon, FALSE);
	
    int i = 0;

    ASSERT(dimof(g_hkHandles)==dimof(g_szHandles));

    for (i=0;i<dimof(g_hkHandles);i++)
        m_cmbPredefRegHandles.AddString(g_szHandles[i]);

    int iSel = AfxGetApp()->GetProfileInt(REG_KEYS, REG_LINK_PREDEFKEY, 0);

    if (iSel<0 || iSel>dimof(g_hkHandles))
        iSel = 0;

    VERIFY(CB_ERR!=m_cmbPredefRegHandles.SelectString(0, g_szHandles[iSel]));


    CString str;
    str = AfxGetApp()->GetProfileString(REG_KEYS, REG_LINK_TARGET, _T(""));
    SetDlgItemText(IDC_EDIT_LINKTARGET, str);

    str = AfxGetApp()->GetProfileString(REG_KEYS, REG_LINK_SOURCE, _T(""));
    SetDlgItemText(IDC_EDIT_LINKSOURCE, str);


	
	return TRUE;  
}

HKEY CLinkcreatDlg::GetPredefinedRegKey(void)const
{
    int iSel = m_cmbPredefRegHandles.GetCurSel();
    ASSERT(CB_ERR!=iSel);
    return g_hkHandles[iSel];
}

void CLinkcreatDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // Ger�tekontext f�r Zeichnen

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Symbol in Client-Rechteck zentrieren
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Symbol zeichnen
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

HCURSOR CLinkcreatDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CLinkcreatDlg::OnBtnCreateLinkTarget() 
{
    //
    // create the sym link:
    //
    LONG lStatus = 0;
    CString strLinkTarget;
    CString strSubKey;
    CString strKey;
    GetDlgItemText(IDC_EDIT_LINKTARGET, strLinkTarget);
    DestroyLinkKey();
    lStatus = CreateSymLinkKey(GetPredefinedRegKey(), strLinkTarget, 
        &m_hLinkKey, 0L);

    if (ERROR_SUCCESS!=lStatus)
    {
        CString strErr;
        strErr.Format(_T("Failed to create symlink key with %ld, attempting to open an existing symlink key"), lStatus);
        AfxMessageBox(strErr);
        lStatus = OpenSymLink(GetPredefinedRegKey(), strLinkTarget, &m_hLinkKey, 0L);
    }

    ShowErrorSuccess(lStatus);
}

void CLinkcreatDlg::OnBtnCreateSrcKey() 
{
	CString str;
    GetDlgItemText(IDC_EDIT_LINKSOURCE, str);
    HKEY hKey = NULL;
	LONG lStatus = RegCreateKeyEx(GetPredefinedRegKey(), str, 0L, NULL, REG_OPTION_NON_VOLATILE,
        KEY_WRITE|KEY_READ, NULL, &hKey, NULL);

    ShowErrorSuccess(lStatus);

    if(hKey)
        RegCloseKey(hKey);
}

void CLinkcreatDlg::OnBtnDeleteLinkTarget() 
{
    CString strLinkTarget;
    LONG lStatus = 0;
    GetDlgItemText(IDC_EDIT_LINKTARGET, strLinkTarget);

    lStatus = DeleteSymLink(GetPredefinedRegKey(), strLinkTarget, 0L);

    ShowErrorSuccess(lStatus);
}

void CLinkcreatDlg::OnBtnDeleteSrcKey() 
{
	CString str;
    GetDlgItemText(IDC_EDIT_LINKSOURCE, str);
	LONG lStatus = RegDeleteKey(GetPredefinedRegKey(), str);

    ShowErrorSuccess(lStatus);
}

void CLinkcreatDlg::OnBtnLinkToSource() 
{
	ASSERT(m_hLinkKey);

	CString str;
    GetDlgItemText(IDC_EDIT_LINKSOURCE, str);
    LONG lStatus = SetSymLink(m_hLinkKey, GetPredefinedRegKey(), str, 0L);

    ShowErrorSuccess(lStatus);
}


void CLinkcreatDlg::DestroyLinkKey(void) 
{
    if(m_hLinkKey)
        VERIFY(ERROR_SUCCESS==RegCloseKey(m_hLinkKey));    
    m_hLinkKey = NULL;
}


void CLinkcreatDlg::OnDestroy() 
{
    CString str;
    GetDlgItemText(IDC_EDIT_LINKTARGET, str);
    AfxGetApp()->WriteProfileString(REG_KEYS, REG_LINK_TARGET, str);
    GetDlgItemText(IDC_EDIT_LINKSOURCE, str);
    AfxGetApp()->WriteProfileString(REG_KEYS, REG_LINK_SOURCE, str);
    AfxGetApp()->WriteProfileInt(REG_KEYS, REG_LINK_PREDEFKEY, m_cmbPredefRegHandles.GetCurSel());


	CDialog::OnDestroy();
	DestroyLinkKey();
}


LRESULT CLinkcreatDlg::OnKickIdle(WPARAM, LPARAM)
{
    CString str;
    GetDlgItemText(IDC_EDIT_LINKTARGET, str);

    GetDlgItem(IDC_BTN_DELETE_LINK_TARGET)->EnableWindow(str.GetLength());
    GetDlgItem(IDC_BTN_CREATE_LINK_TARGET)->EnableWindow(str.GetLength());

    GetDlgItem(IDC_BTN_LINK_TO_SOURCE)->EnableWindow(NULL!=m_hLinkKey);


    GetDlgItemText(IDC_EDIT_LINKSOURCE, str);
    GetDlgItem(IDC_BTN_CREATE_SRC_KEY)->EnableWindow(str.GetLength());
    GetDlgItem(IDC_BTN_DELETE_SRC_KEY)->EnableWindow(str.GetLength());


    Sleep(10);
    return 1;
}


void CLinkcreatDlg::ShowErrorSuccess(LONG lStatus)const
{
    if (ERROR_SUCCESS==lStatus)
        AfxMessageBox(_T("Success"));
    else
    {
        LPBYTE lpMsgBuf = NULL;
        if(FormatMessage( 
            FORMAT_MESSAGE_ALLOCATE_BUFFER | 
            FORMAT_MESSAGE_FROM_SYSTEM | 
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            lStatus,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
            (LPTSTR) &lpMsgBuf,
            0,
            NULL))
        {
            ::MessageBox(m_hWnd, (LPCTSTR)lpMsgBuf, _T("Operation failed!"), MB_OK);
            // Free the buffer.
            LocalFree( lpMsgBuf );
        }
        else
        {
            CString strErr;
            strErr.Format(_T("Operation failed with %ld"), lStatus);
            AfxMessageBox(strErr);
        }
    }    
}	

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Germany Germany
Stefan has been writing programs in C/C++ since 1991, and for Windows since 1993. He holds a German engineer's degree Dipl.-Ing. (FH) in "Microelectronics/Technical Computer Science" from the Aalen (Germany) University of Applied Sciences and an MSc in "Software Technology" from the Stuttgart (Germany) University of Applied Sciences. Currently, he is employed by a software company in the south-west of Germany that specializes in PC life-cycle products and software deployment technology. In his spare time, Stefan likes to go swimming and enjoys listening to jazz music from the fifties. And yes, he has a Weblog at http://mcblogs.craalse.de/sku (German only).

Comments and Discussions