Problem with ioctl FSCTL_SET_REPARSE_POINT

  • Thread starter Thread starter Mathieu
  • Start date Start date
M

Mathieu

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.

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

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,

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;
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; }

thank you for help
 
Back
Top