FSCTL_SET_REPARSE_POINT ok , but error invalid parameter

Hello,

I’am finish developped a virtual disk RAW , it’s OK , 14 hours of developpment and debuggage , no BSOD when i mount a virtualdisk .

OK for all.

Now when i try mount directory (eg c:\vol) (to my device driver disk raw with ioctl FSCTL_SET_REPARSE_POINT, it’s ok , deviceiocontrol return true.

Problem : When i click in windows explorer in the directory “c:\vol” , i’am a dialogbox showing error “Param?tre incorrect” “invalid parameter”, worse , ANY FUNCTION IOCTL of my driver are called (aucune fonction IOCTL appel? dans mon driver).

I’am need help , thank you.

source code :

#define IO_REPARSE_TAG_SYMLINK 0xa000000c
#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,

HANDLE OpenDirectory(WCHAR *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;
}

int MountDir(WCHAR *directory,WCHAR *target)
{
HANDLE hDir = OpenDirectory(directory, TRUE);
int err=GetLastError();
if (hDir!=INVALID_HANDLE_VALUE)
{
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)]={0};
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_SYMLINK;
/*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);
err=GetLastError();
CloseHandle(hDir);
}
return err;

}

HANDLE _stdcall VDRS_MountRAWDisk(PVDRS header,int *error)
{




bool ismounteddirectory=false;
bool isdefinedevice=false;
if (_header.in.Letter!=NULL)
{
if ((wcslen(_header.in.Letter)==2) && (_header.in.Letter[1]==L’:‘))
isdefinedevice=true;
else
ismounteddirectory=true;
}
}
TDISKRAW_CREATE tdiskcreate={0};
wcscpy(tdiskcreate._taglicense,L"test");
wcscpy(tdiskcreate._taguser,_header.in.taguser);
tdiskcreate.in_namedos[0]=0;
WCHAR nametmp[64]={0};
if (isdefinedevice)
swprintf(tdiskcreate.in_namedos,L"\DosDevices\Global\%ws",_header.in.Letter);
if (ismounteddirectory)
{
for (int x = 0 ;x<32;x++)
{
UCHAR ch=(rand()%26)+L’A’;
nametmp=ch;
}

swprintf(tdiskcreate.in_namedos,L"\DosDevices\Global\%ws",nametmp);

}
if (control(hMain,IOCTL_CMD_RAW_CREATEVIRTUALDISK,&tdiskcreate,sizeof(tdiskcreate),&tdiskcreate,sizeof(tdiskcreate),cb))
{



if (isdefinedevice)
{
bool okdosdevice=DefineDosDeviceW(DDD_RAW_TARGET_PATH,_header.in.Letter,h->namedevice);
if (!okdosdevice)
_error=6;
}
else
{
WCHAR routedevice[512];
//swprintf(routedevice,L"\??\Volume{%ws}\“,nametmp);
swprintf(routedevice,L”\??\%ws\",nametmp);
int err=MountDir(h->letter,routedevice);
if (err!=0)
_error=7;
}
}

Here my party source code and i don’t understand what explorer.exe show dialogbox “Invalid Parameter”.

Thank you.