What is the Win32 (Vista and later) equivalent? Presumably there is
one, since from the command line, dir displays the desired information
for symbolic links.
TIA,
--Beman
[Symbolic Link Effects on File Systems Functions]
http://msdn.microsoft.com/en-us/library/aa365682(VS.85).aspx
[Symbolic Links]
http://msdn.microsoft.com/en-us/library/aa365680(VS.85).aspx
Read about "Hard Links", "Junktions",...also have a look at IOCTL's
like FSCTL_GET_REPARSE_POINT and familiar for more information.
You should also pass the symbolic link handle opened with CreateFile(...)
to GetFinalPathNameByHandle(...) to get the target file, that works Vista
and
upper only. AFAIK this also works for UNC Paths (local only!),...
Good Luck!
Regards
Kerem
--
-----------------------
Beste Gr�sse / Best regards / Votre bien devoue
Kerem G�mr�kc�
Latest Project: http://www.pro-it-education.de/software/deviceremover
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------
"Beman Dawes" <beman...@gmail.com> schrieb im Newsbeitrag
news:d87675af-86d1-4977...@z41g2000yqz.googlegroups.com...
> [Symbolic Link Effects on File Systems Functions]http://msdn.microsoft.com/en-us/library/aa365682(VS.85).aspx
>
> [Symbolic Links]http://msdn.microsoft.com/en-us/library/aa365680(VS.85).aspx
>
> Read about "Hard Links", "Junktions",...also have a look at IOCTL's
> like FSCTL_GET_REPARSE_POINT and familiar for more information.
Ah! I'd missed that. Works well. See sample program below.
> You should also pass the symbolic link handle opened with CreateFile(...)
> to GetFinalPathNameByHandle(...) to get the target file, that works Vista
> and
> upper only. AFAIK this also works for UNC Paths (local only!),...
The reported hangs with GetFinalPathNameByHandle(...) scared me off
from that approach.
See http://www.codeproject.com/Articles/35202/GetFinalPathNameByHandle-API-Hangs.aspx
Thanks for the sugestions! Very helpful!
--Beman
------------
#include <windows.h>
#include <string>
#include <iostream>
// REPARSE_DATA_BUFFER related definitions are found in ntifs.h,
// which is part of the Device Driver Kit rather than the SDK.
// See http://msdn.microsoft.com/en-us/library/ms791514.aspx
#define SYMLINK_FLAG_RELATIVE 1
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
USHORT ReparseDataLength;
USHORT Reserved;
union {
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
ULONG Flags;
WCHAR PathBuffer[1];
/* Example of distinction between substitute and print names:
mklink /d ldrive c:\
SubstituteName: c:\\??\
PrintName: c:\
*/
} SymbolicLinkReparseBuffer;
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
WCHAR PathBuffer[1];
} MountPointReparseBuffer;
struct {
UCHAR DataBuffer[1];
} GenericReparseBuffer;
};
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
#define REPARSE_DATA_BUFFER_HEADER_SIZE \
FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
int main(int argc, char * argv[])
{
union info_t
{
char buf[REPARSE_DATA_BUFFER_HEADER_SIZE
+MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
REPARSE_DATA_BUFFER rdb;
} info;
HANDLE h = ::CreateFile(argv[1], GENERIC_READ, 0, 0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_OPEN_REPARSE_POINT, 0);
if (h == INVALID_HANDLE_VALUE)
{
std::cout << "INVALID_HANDLE_VALUE\n";
return 1;
}
DWORD sz;
if (::DeviceIoControl(
h, // file or directory handle
FSCTL_GET_REPARSE_POINT, // dwIoControlCode
0, // lpInBuffer
0, // nInBufferSize
info.buf, // output buffer
sizeof(info), // size of output buffer
&sz, // number of bytes returned
0 // OVERLAPPED structure
) == 0)
{
std::cout << "Error: " << ::GetLastError() << "\n";
if (::GetLastError() == 4390L) std::cout <<
"ERROR_NOT_A_REPARSE_POINT\n";
return 1;
}
std::cout
<< "REPARSE_DATA_BUFFER_HEADER_SIZE: "
<< REPARSE_DATA_BUFFER_HEADER_SIZE << '\n'
<< "info.rdb.ReparseDataLength: "
<< info.rdb.ReparseDataLength << '\n'
<< "info.rdb.SymbolicLinkReparseBuffer.SubstituteNameOffset: "
<< info.rdb.SymbolicLinkReparseBuffer.SubstituteNameOffset << '\n'
<< "info.rdb.SymbolicLinkReparseBuffer.SubstituteNameLength: "
<< info.rdb.SymbolicLinkReparseBuffer.SubstituteNameLength << '\n'
<< "info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset: "
<< info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset << '\n'
<< "info.rdb.SymbolicLinkReparseBuffer.PrintNameLength: "
<< info.rdb.SymbolicLinkReparseBuffer.PrintNameLength << '\n'
<< "info.rdb.SymbolicLinkReparseBuffer.Flags: "
<< info.rdb.SymbolicLinkReparseBuffer.Flags << std::endl;
std::wstring subname(
(wchar_t*)info.rdb.SymbolicLinkReparseBuffer.PathBuffer
+ info.rdb.SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof
(wchar_t),
(wchar_t*)info.rdb.SymbolicLinkReparseBuffer.PathBuffer
+ info.rdb.SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof
(wchar_t)
+ info.rdb.SymbolicLinkReparseBuffer.SubstituteNameLength/sizeof
(wchar_t));
std::wstring prtname(
(wchar_t*)info.rdb.SymbolicLinkReparseBuffer.PathBuffer
+ info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof
(wchar_t),
(wchar_t*)info.rdb.SymbolicLinkReparseBuffer.PathBuffer
+ info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof
(wchar_t)
+ info.rdb.SymbolicLinkReparseBuffer.PrintNameLength/sizeof
(wchar_t));
std::wcout
<< L"SubstituteName: " << subname
<< L", PrintName: " << prtname << std::endl;
return 0;
}
you are welcome Bernan and thanks for posting the
sample here, always good if someone needs one!
Regards
Kerem
--
-----------------------
Beste Gr�sse / Best regards / Votre bien devoue
Kerem G�mr�kc�
Latest Project: http://www.pro-it-education.de/software/deviceremover
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------
"Beman Dawes" <beman...@gmail.com> schrieb im Newsbeitrag
news:9cb182b8-4fff-49e4...@m25g2000yqc.googlegroups.com...