1 module symlinkd.windows;
2 
3 version (Windows):
4 
5 import core.sys.windows.windows;
6 
7 extern (Windows) nothrow @nogc
8 {
9 	enum
10 	{
11 		/// The link target is a directory.
12 		SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1,
13 		/**
14 		 * Specify this flag to allow creation of symbolic links when the process is not elevated.
15 		 * Developer Mode must first be enabled on the machine before this option will function.
16 		 */
17 		SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x2
18 	}
19 
20 	/**
21 		Creates a symbolic link.
22 
23 		Params:
24 			lpSymlinkFileName =
25 				The symbolic link to be created.
26 
27 				This parameter may include the path. In the ANSI version of this function, the name
28 				is limited to `MAX_PATH` characters. To extend this limit to 32,767 wide characters,
29 				call the Unicode version of the function and prepend "\\?\" to the path.
30 
31 			lpTargetFileName =
32 				The name of the target for the symbolic link to be created.
33 
34 				If `lpTargetFileName` has a device name associated with it, the link is treated as an
35 				absolute link; otherwise, the link is treated as a relative link.
36 
37 				This parameter may include the path. In the ANSI version of this function, the name is
38 				limited to `MAX_PATH` characters. To extend this limit to 32,767 wide characters,
39 				call the Unicode version of the function and prepend "\\?\" to the path.
40 
41 			dwFlags =
42 				Indicates whether the link target, `lpTargetFileName`, is a directory.
43 
44 				`0x0`                                          - The link target is a file.
45 				`SYMBOLIC_LINK_FLAG_DIRECTORY`                 - The link target is a directory.
46 				`SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE` - Specify this flag to allow creation of symbolic links when the process is not elevated.
47 				                                                 Developer Mode must first be enabled on the machine before this option will function.
48 
49 		Returns:
50 			If the function succeeds, the return value is nonzero.
51 			If the function fails, the return value is zero. To get extended error information, call GetLastError.
52 	*/
53 	BOOLEAN CreateSymbolicLinkA(LPCSTR  lpSymlinkFileName, LPCSTR  lpTargetFileName, DWORD dwFlags);
54 	/// ditto
55 	BOOLEAN CreateSymbolicLinkW(LPCWSTR lpSymlinkFileName, LPCWSTR lpTargetFileName, DWORD dwFlags);
56 
57 	version (Unicode)
58 	{
59 		alias CreateSymbolicLink = CreateSymbolicLinkW;
60 	}
61 	else
62 	{
63 		alias CreateSymbolicLink = CreateSymbolicLinkA;
64 	}
65 
66 	enum
67 	{
68 		/// Return the normalized drive name. This is the default.
69 		FILE_NAME_NORMALIZED = 0x0,
70 		/// Return the opened file name (not normalized).
71 		FILE_NAME_OPENED     = 0x8
72 	}
73 
74 	enum
75 	{
76 		/// Return the path with the drive letter. This is the default.
77 		VOLUME_NAME_DOS  = 0x0,
78 		/// Return the path with a volume GUID path instead of the drive name.
79 		VOLUME_NAME_GUID = 0x1,
80 		/// Return the path with no drive information.
81 		VOLUME_NAME_NONE = 0x4,
82 		/// Return the path with the volume device path.
83 		VOLUME_NAME_NT   = 0x2
84 	}
85 
86 	/**
87 		Retrieves the final path for the specified file.
88 
89 		Params:
90 			hFile = A handle to a file or directory.
91 			
92 			lpszFilePath = A pointer to a buffer that receives the path of `hFile`.
93 
94 			cchFilePath = The size of `lpszFilePath`, in `TCHAR`s. This value does not include a `NULL` termination character.
95 
96 			dwFlags = The type of result to return. This parameter can be one of the following values.
97 
98 			          `FILE_NAME_NORMALIZED` - Return the normalized drive name. This is the default.
99 			          `FILE_NAME_OPENED`     - Return the opened file name (not normalized).
100 
101 			          This parameter can also include one of the following values.
102 
103 			          `VOLUME_NAME_DOS`  - Return the path with the drive letter. This is the default.
104 			          `VOLUME_NAME_GUID` - Return the path with a volume GUID path instead of the drive name.
105 			          `VOLUME_NAME_NONE` - Return the path with no drive information.
106 			          `VOLUME_NAME_NT`   - Return the path with the volume device path.
107 
108 		Returns:
109 			If the function succeeds, the return value is the length of the string received by `lpszFilePath`, in `TCHAR`s.
110 			This value does not include the size of the terminating null character.
111 
112 			Windows Server 2008 and Windows Vista: For the ANSI version of this function, `GetFinalPathNameByHandleA`, the
113 			return value includes the size of the terminating null character.
114 
115 			If the function fails because `lpszFilePath` is too small to hold the string plus the terminating null character,
116 			the return value is the required buffer size, in `TCHAR`s. This value includes the size of the terminating null character.
117 
118 			If the function fails for any other reason, the return value is zero. To get extended error information, call `GetLastError`.
119 
120 
121 			`ERROR_PATH_NOT_FOUND`   - Can be returned if you are searching for a drive letter and one does not exist.
122 			                           For example, the handle was opened on a drive that is not currently mounted, or
123 			                           if you create a volume and do not assign it a drive letter. If a volume has no
124 			                           drive letter, you can use the volume GUID path to identify it.
125 			                           
126 			                           This return value can also be returned if you are searching for a volume GUID
127 			                           path on a network share. Volume GUID paths are not created for network shares.
128 
129 			`ERROR_NOT_ENOUGH_MEMORY` - Insufficient memory to complete the operation.
130 
131 			`ERROR_INVALID_PARAMETER` - Invalid flags were specified for `dwFlags`. 
132 	*/
133 	uint GetFinalPathNameByHandleA(HANDLE hFile, LPSTR  lpszFilePath, uint cchFilePath, uint dwFlags);
134 	/// ditto
135 	uint GetFinalPathNameByHandleW(HANDLE hFile, LPWSTR lpszFilePath, uint cchFilePath, uint dwFlags);
136 
137 	version (Unicode)
138 	{
139 		alias GetFinalPathNameByHandle = GetFinalPathNameByHandleW;
140 	}
141 	else
142 	{
143 		alias GetFinalPathNameByHandle = GetFinalPathNameByHandleA;
144 	}
145 }