Windows System Programming: Creating HardLinks and SoftLinks
Tags: windows, systemprogramming, cpp
Published: 2020-08-30 13:08:07

Hello, In this post you will learn about creating hard-links and soft-links in the windows using C++.

If you are familiar with Linux, you must have heard of "**symlinks**". It helps you to create alias of files or directories containing reference to in the form of an absolute or relative path. But in windows, you can create hard-links only for the files. If you will delete the original file, you can still have access to the hard-linked file.

The difference between copied file and hard-linked file is that, in the copied file, you will get the independent copy of the file, which means both of two files are not linked with each other. Now in hard-linked file, if you would change any content in hard-link file, it will be reflected back to the original file and vice-versa.

You can create hardlink by using [**CreateHardLinkA**](https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createhardlinka) function from [_winbase.h_](https://docs.microsoft.com/en-us/windows/win32/api/winbase/) header file

```cpp
BOOL CreateHardLinkA(
  LPCSTR                lpFileName,
  LPCSTR                lpExistingFileName,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
```
Function parameter description as follows
+ **lpFileName** &rarr; The name of the new hard link file.
+ **lpExistingFileName** &rarr; The name of the existing file whose hard-link you want to create. 
+ **lpSecurityAttributes** &rarr; Security attributes for the hard-link. It is **reserved** and **must** be set to `NULL`

So here is the complete code snippet, for create hard-link of a file
```cpp
#include <Windows.h>
#include <string>
#include <iostream>
#include <WinBase.h>

int main(int argc, char**argv)
{
	if (argc < 3) {
		printf("usage: %s <existing file name> <new file name>\n", argv[0]);
		return 1;
	}

	/**
	  * https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createhardlinka
	  */
	BOOL hlBool = CreateHardLinkA(argv[2], argv[1], NULL);
	
	if (hlBool) {
		printf("Hard link created\n");
		return 0;
	}
	else {
		printf("Error Code: %d\n", GetLastError());
		return 1;
	}
}
```

Now, let's work on creating soft-links. Soft-link (aka symlink) is simply a shortcut of the file (yes, you have created it already via context menu :D). Unlike the hard-links, it can be created both for file and a directory and if you would delete the original file, you can't access the file via soft-link.

You can create a symbolic link using [**CreateSymbolicLinkA**](https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createsymboliclinka) function from  [_winbase.h_](https://docs.microsoft.com/en-us/windows/win32/api/winbase/)

```cpp
BOOLEAN CreateSymbolicLinkA(
  LPCSTR lpSymlinkFileName,
  LPCSTR lpTargetFileName,
  DWORD  dwFlags
);
```
Function parameters description as follows
+ **lpSymlinkFileName** &rarr; The path of symbolic link to be created
+ **lpTargetFileName** &rarr; The path of the target for the symbolic link to be created
+ **dwFlags** &rarr; This Indicates whether the link target, `lpTargetFileName`, is a directory.
   + `0x0` &rarr; The link target is a file.
   + `0x1` &rarr; The link target is a directory.

Complete code as follows
```cpp
#include <Windows.h>
#include <string>
#include <iostream>
#include <WinBase.h>
#include <fileapi.h>
#define print printf

int main(int argc, char** argv) {
	if (argc < 3) {
		printf("usage: %s <existing file name> <new file name>\n", argv[0]);
		return 1;
	}

	DWORD flags = 0x0; // flag for creating symlink of a file

	if (GetFileAttributesA(argv[1]) == FILE_ATTRIBUTE_DIRECTORY) {
		print("dir");
		flags = SYMBOLIC_LINK_FLAG_DIRECTORY; // flag for creatng symlink of directory
	}

	/**
	  * https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createsymboliclinka
	  */
	BOOLEAN slBool = CreateSymbolicLinkA(argv[2], argv[1], flags);

	if (slBool) {
		printf("Symlink created\n");
		return 0;
	}
	else {
		DWORD err = GetLastError();
		if (err == 1314) {
			printf("Try again with administrator account\n");
			return 1;
		}
		printf("Error Code: %d\n", err);
		return 1;
	}
}
```
 
**NOTE** If you want to create a soft-link, without running the process with Administrator account, you can set the value of `dwFlags` to `SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE`. Make sure you enable the [developer mode](https://docs.microsoft.com/en-us/windows/uwp/get-started/enable-your-device-for-development) before using this flag

Thanks for reading this post. Follow the links to reach me

+ Email: tbhaxor@gmail.com
+ Twitter: [@tbhaxor](https://twitter.com/tbhaxor)
+ Facebook: [@tbhaxor](https://fb.com/tbhaxor)
+ GitHub: [@tbhaxor](https://github.com/tbhaxor)
+ LinkedIn: [@gurkirat--singh](https://www.linkedin.com/in/gurkirat--singh)
+ Instagram: [@_tbhaxor_](https://instagram.com/_tbhaxor_)