bool ModifyReparsePoint(const wchar_t *Object,const wchar_t *NewData) { bool Result=false; LPBYTE szBuff=new BYTE[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; if(szBuff) { PREPARSE_DATA_BUFFER rdb=reinterpret_cast<PREPARSE_DATA_BUFFER>(szBuff); if (GetREPARSE_DATA_BUFFER(Object,rdb)) { bool FillResult=false; switch (rdb->ReparseTag) { case IO_REPARSE_TAG_MOUNT_POINT: { string strPrintName,strSubstituteName; ConvertNameToFull(NewData,strPrintName); strSubstituteName=L"\\??\\"; strSubstituteName+=(strPrintName.CPtr()+(HasPathPrefix(strPrintName)?4:0)); FillResult=FillREPARSE_DATA_BUFFER(rdb,strPrintName,strPrintName.GetLength(),strSubstituteName,strSubstituteName.GetLength()); } break; case IO_REPARSE_TAG_SYMLINK: { string strPrintName=NewData,strSubstituteName=NewData; if (IsAbsolutePath(NewData)) { strSubstituteName=L"\\??\\"; strSubstituteName+=(strPrintName.CPtr()+(HasPathPrefix(strPrintName)?4:0)); rdb->SymbolicLinkReparseBuffer.Flags=0; } else { rdb->SymbolicLinkReparseBuffer.Flags=SYMLINK_FLAG_RELATIVE; } FillResult=FillREPARSE_DATA_BUFFER(rdb,strPrintName,strPrintName.GetLength(),strSubstituteName,strSubstituteName.GetLength()); } break; } if (FillResult) { Result=SetREPARSE_DATA_BUFFER(Object,rdb); } else { SetLastError(ERROR_INSUFFICIENT_BUFFER); } } delete[] szBuff; } return Result; }
bool ModifyReparsePoint(const string& Object,const string& NewData) { block_ptr<REPARSE_DATA_BUFFER> rdb(MAXIMUM_REPARSE_DATA_BUFFER_SIZE); if (!GetREPARSE_DATA_BUFFER(Object, rdb.get())) return false; switch (rdb->ReparseTag) { case IO_REPARSE_TAG_MOUNT_POINT: { const auto strPrintName = ConvertNameToFull(NewData); const auto strSubstituteName = KernelPath(NTPath(strPrintName)); if (!FillREPARSE_DATA_BUFFER(rdb.get(), strPrintName, strSubstituteName)) { SetLastError(ERROR_INSUFFICIENT_BUFFER); return false; } } break; case IO_REPARSE_TAG_SYMLINK: { const auto& strPrintName = NewData; auto strSubstituteName = NewData; if (IsAbsolutePath(NewData)) { strSubstituteName = KernelPath(NTPath(strSubstituteName)); rdb->SymbolicLinkReparseBuffer.Flags=0; } else { rdb->SymbolicLinkReparseBuffer.Flags=SYMLINK_FLAG_RELATIVE; } if (!FillREPARSE_DATA_BUFFER(rdb.get(), strPrintName, strSubstituteName)) { SetLastError(ERROR_INSUFFICIENT_BUFFER); return false; } } break; default: return false; } return SetREPARSE_DATA_BUFFER(Object,rdb.get()); }
bool DuplicateReparsePoint(const wchar_t *Src,const wchar_t *Dst) { bool Result=false; LPBYTE szBuff=new BYTE[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; if(szBuff) { PREPARSE_DATA_BUFFER rdb=reinterpret_cast<PREPARSE_DATA_BUFFER>(szBuff); if (GetREPARSE_DATA_BUFFER(Src,rdb) && SetREPARSE_DATA_BUFFER(Dst,rdb)) { Result=true; } delete[] szBuff; } return Result; }
bool DuplicateReparsePoint(const string& Src,const string& Dst) { block_ptr<REPARSE_DATA_BUFFER> rdb(MAXIMUM_REPARSE_DATA_BUFFER_SIZE); return GetREPARSE_DATA_BUFFER(Src, rdb.get()) && SetREPARSE_DATA_BUFFER(Dst, rdb.get()); }
bool CreateReparsePoint(const string& Target, const string& Object,ReparsePointTypes Type) { bool Result=false; { switch (Type) { case RP_HARDLINK: break; case RP_EXACTCOPY: Result=DuplicateReparsePoint(Target,Object); break; case RP_SYMLINK: case RP_SYMLINKFILE: case RP_SYMLINKDIR: { os::fs::file_status ObjectStatus(Object); if(Type == RP_SYMLINK) { Type = os::fs::is_directory(Target)? RP_SYMLINKDIR : RP_SYMLINKFILE; } if (imports.CreateSymbolicLinkW && !os::fs::exists(ObjectStatus)) { Result=os::fs::CreateSymbolicLink(Object,Target,Type==RP_SYMLINKDIR?SYMBOLIC_LINK_FLAG_DIRECTORY:0); } else { const auto ObjectCreated = Type==RP_SYMLINKDIR? os::fs::is_directory(ObjectStatus) || os::fs::create_directory(Object) : os::fs::is_file(ObjectStatus) || os::fs::file(Object, 0, 0, nullptr, CREATE_NEW); if (ObjectCreated) { block_ptr<REPARSE_DATA_BUFFER> rdb(MAXIMUM_REPARSE_DATA_BUFFER_SIZE); rdb->ReparseTag=IO_REPARSE_TAG_SYMLINK; const auto& strPrintName = Target; auto strSubstituteName = Target; if (IsAbsolutePath(Target)) { strSubstituteName = KernelPath(NTPath(strSubstituteName)); rdb->SymbolicLinkReparseBuffer.Flags=0; } else { rdb->SymbolicLinkReparseBuffer.Flags=SYMLINK_FLAG_RELATIVE; } if (FillREPARSE_DATA_BUFFER(rdb.get(), strPrintName, strSubstituteName)) { Result=SetREPARSE_DATA_BUFFER(Object,rdb.get()); } else { SetLastError(ERROR_INSUFFICIENT_BUFFER); } } } } break; case RP_JUNCTION: case RP_VOLMOUNT: { const auto strPrintName = ConvertNameToFull(Target); auto strSubstituteName = KernelPath(NTPath(strPrintName)); block_ptr<REPARSE_DATA_BUFFER> rdb(MAXIMUM_REPARSE_DATA_BUFFER_SIZE); rdb->ReparseTag=IO_REPARSE_TAG_MOUNT_POINT; if (FillREPARSE_DATA_BUFFER(rdb.get(), strPrintName, strSubstituteName)) { Result=SetREPARSE_DATA_BUFFER(Object,rdb.get()); } else { SetLastError(ERROR_INSUFFICIENT_BUFFER); } } break; } } return Result; }
bool WINAPI CreateReparsePoint(const wchar_t *Target, const wchar_t *Object,DWORD Type) { bool Result=false; if (Object && *Object && Target && *Target) { switch (Type) { case RP_EXACTCOPY: Result=DuplicateReparsePoint(Target,Object); break; case RP_SYMLINK: case RP_SYMLINKFILE: case RP_SYMLINKDIR: if(Type == RP_SYMLINK) { DWORD Attr = apiGetFileAttributes(Target); Type = ((Attr != INVALID_FILE_ATTRIBUTES) && (Attr&FILE_ATTRIBUTE_DIRECTORY)? RP_SYMLINKDIR : RP_SYMLINKFILE); } if (ifn.pfnCreateSymbolicLink) { Result=apiCreateSymbolicLink(Object,Target,Type==RP_SYMLINKDIR?SYMBOLIC_LINK_FLAG_DIRECTORY:0); } else { bool ObjectCreated=false; if (Type==RP_SYMLINKDIR) { ObjectCreated=apiCreateDirectory(Object,nullptr)!=FALSE; } else { File file; if(file.Open(Object,0,0,nullptr,CREATE_NEW)) { ObjectCreated=true; file.Close(); } } if (ObjectCreated) { LPBYTE szBuff=new BYTE[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; if(szBuff) { PREPARSE_DATA_BUFFER rdb=reinterpret_cast<PREPARSE_DATA_BUFFER>(szBuff); rdb->ReparseTag=IO_REPARSE_TAG_SYMLINK; string strPrintName=Target,strSubstituteName=Target; if (IsAbsolutePath(Target)) { strSubstituteName=L"\\??\\"; strSubstituteName+=(strPrintName.CPtr()+(HasPathPrefix(strPrintName)?4:0)); rdb->SymbolicLinkReparseBuffer.Flags=0; } else { rdb->SymbolicLinkReparseBuffer.Flags=SYMLINK_FLAG_RELATIVE; } if (FillREPARSE_DATA_BUFFER(rdb,strPrintName,strPrintName.GetLength(),strSubstituteName,strSubstituteName.GetLength())) { Result=SetREPARSE_DATA_BUFFER(Object,rdb); } else { SetLastError(ERROR_INSUFFICIENT_BUFFER); } delete[] szBuff; } } } break; case RP_JUNCTION: case RP_VOLMOUNT: { string strPrintName,strSubstituteName; ConvertNameToFull(Target,strPrintName); strSubstituteName=L"\\??\\"; strSubstituteName+=(strPrintName.CPtr()+(HasPathPrefix(strPrintName)?4:0)); BYTE szBuff[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; PREPARSE_DATA_BUFFER rdb=reinterpret_cast<PREPARSE_DATA_BUFFER>(szBuff); rdb->ReparseTag=IO_REPARSE_TAG_MOUNT_POINT; if (FillREPARSE_DATA_BUFFER(rdb,strPrintName,strPrintName.GetLength(),strSubstituteName,strSubstituteName.GetLength())) { Result=SetREPARSE_DATA_BUFFER(Object,rdb); } else { SetLastError(ERROR_INSUFFICIENT_BUFFER); } } break; } } return Result; }