通过Windows api,CreateSymbolicLink可以创建软链接,但是不能直接获取到软链接目标位置,
GetFileAttributes通过属性FILE_ATTRIBUTE_REPARSE_POINT可以知道,文件/目录是一个符号链接
GetFinalPathNameByHandle可以获取软链接对应的真实设备路径,设备路径是\Device\HarddiskVolumex\xxxx\xxx,不知道盘符
GetVolumePathName可以通过\Device\HarddiskVolumex\xxxx\xxx获取到盘符c:\,但是不会自动拼接为盘符对应的文件全路径
QueryDosDevice可以通过盘符获取盘符c:对应的设备路径\Device\HarddiskVolumex
于是,做个拼接就可以了
void getSymbolicLinkTargetPath(const char* symbolicFilePath) {
CHAR Path[MAX_PATH], TmpPath[MAX_PATH], TargetPath[MAX_PATH];
HANDLE hFile;
DWORD dwRet;
hFile = CreateFileA(symbolicFilePath, // file to open
GENERIC_READ, // open for reading
FILE_SHARE_READ | FILE_SHARE_WRITE, // share for reading
NULL, // default security
OPEN_EXISTING, // existing file only
FILE_FLAG_BACKUP_SEMANTICS, // for directory
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
printf("Could not open file %s (error %d\n)", symbolicFilePath, GetLastError());
return;
}
dwRet = GetFinalPathNameByHandleA(hFile, Path, MAX_PATH, VOLUME_NAME_NT);
if (dwRet < MAX_PATH)
{
printf("\nThe final path is: %s\n", Path);
strcpy_s(TargetPath, ARR_SIZE(TargetPath), Path);
// get "c://"
BOOL bRet = GetVolumePathNameA(Path, TmpPath, MAX_PATH);
printf("\GetVolumePathName is: %s\n", TmpPath);
// make c:, not "c://",
TmpPath[2] = 0;
memset(Path, 0, ARR_SIZE(Path));
// c: => /Dosdevice/HardDiskVolumn1
dwRet = QueryDosDeviceA(TmpPath, Path, MAX_PATH);
printf("\nQueryDosDevice is: %s=>%s\n", TmpPath, Path);
// calculate len
char* pos = ((char*)TargetPath) + strlen(Path);
pos -= strlen(TmpPath);
char* rPos = pos;
char* tPos = (char*)TmpPath;
while (*tPos) {
*pos = *tPos;
++pos;
++tPos;
}
printf("\nTargetPath: %s\n", rPos);
}
else {
printf("\nThe required buffer size is %d.\n", dwRet);
}
CloseHandle(hFile);
}