Problem with ioctl FSCTL_SET_REPARSE_POINT

Hi

I’am being developpe a drive virtual disk file system.
When I call API definedosdevice on my name device , it’s OK, it works for a drive letter I can see virtual files and virtual directory.

I’am try with the command IOCTL FSCTL_SET_REPARSE_POINT to make a link empty directory on my virtual disk containing some virtual files installed
with DeviceType = FILE_DEVICE_DISK_FILE_SYSTEM and devicecharacteristics = FILE_DEVICE_IS_MOUNTED , it’s ok for command IOCTL FSCTL_SET_REPARSE_POINT.

Problem :
it’s don’t work when click directory linked to
my disk containing virtual files.
explorer.exe show my error “The data present in the reparse point buffer is invalid”.

Can you help please ?

In this forum I have already attached the party source code on the thread “Blue screen on API CreateFileMapping: A thread tried to release a resource it Did No”

Thank you better.

I don’t think you should use the FSCTL_SET_REPARSE_POINT IOCTL to set volume
mount points. You would need to set up the GenericReparseBuffer structure
properly and I’m not sure that’s documented.

However, there is a user mode API you can call, SetVolumeMountPoint
(currently at
http://msdn.microsoft.com/en-us/library/aa365561(v=VS.85).aspx), which has
been working great for me. However I’m not using DefineDosDevice but instead
I use MountMgr to manage my drive letters.

Thanks,
Alex.

SetVolumeMountpoint return error 87.
I try sample SlxMountvol , it’s don’t work.

Here is my source code for make link of directory c:\vol to target :

Need help ;

void test(WCHAR *target)
{
HANDLE hDir = OpenDirectory(“c:\vol\”, TRUE);

WCHAR szTarget[128];
wcscpy(szTarget,target);
// Take note that buf and ReparseBuffer occupy the same space
BYTE buf[sizeof(REPARSE_MOUNTPOINT_DATA_BUFFER) + MAX_PATH * sizeof(WCHAR)];
REPARSE_MOUNTPOINT_DATA_BUFFER& ReparseBuffer = (REPARSE_MOUNTPOINT_DATA_BUFFER&)buf;
int len=wcslen(szTarget);
// Prepare reparse point data
memset(buf, 0, sizeof(buf));
//ReparseBuffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
ReparseBuffer.ReparseTag =IO_REPARSE_TAG_MOUNT_POINT;
/*int len = ::MultiByteToWideChar(CP_ACP, 0, szTarget, -1,
ReparseBuffer.ReparseTarget, MAX_PATH);*/
ReparseBuffer.ReparseTargetMaximumLength = (len–) * sizeof(WCHAR);
ReparseBuffer.ReparseTargetLength = len * sizeof(WCHAR);
ReparseBuffer.ReparseDataLength = ReparseBuffer.ReparseTargetLength + 12;
wcscpy(ReparseBuffer.ReparseTarget,szTarget);

// Attach reparse point
DWORD dwRet;
SetLastError(0);
::DeviceIoControl(hDir, FSCTL_SET_REPARSE_POINT, &ReparseBuffer,
ReparseBuffer.ReparseDataLength+REPARSE_MOUNTPOINT_HEADER_SIZE,
NULL, 0, &dwRet, NULL);
int err=GetLastError(); //err=0;
dwRet=dwRet;

}

i complete source code :

HANDLE OpenDirectory(LPCTSTR pszPath, BOOL bReadWrite) {
// Obtain backup/restore privilege in case we don’t have it
HANDLE hToken;
TOKEN_PRIVILEGES tp;
::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
::LookupPrivilegeValue(NULL,
(bReadWrite ? SE_RESTORE_NAME : SE_BACKUP_NAME),
&tp.Privileges[0].Luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
::AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
::CloseHandle(hToken);

// Open the directory
DWORD dwAccess = bReadWrite ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_READ;
HANDLE hDir = ::CreateFile(pszPath, dwAccess, 0, NULL, OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);

return hDir;
}

#define REPARSE_MOUNTPOINT_HEADER_SIZE 8

typedef struct {
DWORD ReparseTag;
DWORD ReparseDataLength;
WORD Reserved;
WORD ReparseTargetLength;
WORD ReparseTargetMaximumLength;
WORD Reserved1;
WCHAR ReparseTarget[1];
} REPARSE_MOUNTPOINT_DATA_BUFFER, *PREPARSE_MOUNTPOINT_DATA_BUFFER;

typedef struct _REPARSE_DATA_BUFFER {
DWORD ReparseTag;
WORD ReparseDataLength;
WORD Reserved;
union {
struct {
WORD SubstituteNameOffset;
WORD SubstituteNameLength;
WORD PrintNameOffset;
WORD PrintNameLength;
WCHAR PathBuffer[1];
} SymbolicLinkReparseBuffer;
struct {
WORD SubstituteNameOffset;
WORD SubstituteNameLength;
WORD PrintNameOffset;
WORD PrintNameLength;
WCHAR PathBuffer[1];
} MountPointReparseBuffer;
struct {
BYTE DataBuffer[1];
} GenericReparseBuffer;
};
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;

#define REPARSE_DATA_BUFFER_HEADER_SIZE \
FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)

#define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) // REPARSE_DATA_BUFFER,