Hi, Try as I might, I just cannot get Dir.create_junction to work with FFI in the ffi branch of the win32-dir project. The problem is the REPARSE_JDATA_BUFFER struct. I''m just not sure how to set those members, specifically, the PathBuffer member. The target looks good, it''s UTF-16LE encoded, but I can''t make it work, despite trying several ways of defining the struct, and setting various struct members. A quick gist for reference: https://gist.github.com/2721257 Help much appreciated! Regards, Dan
Hi, 2012/5/18 Daniel Berger <djberg96 at gmail.com>> Hi, > > Try as I might, I just cannot get Dir.create_junction to work with FFI > in the ffi branch of the win32-dir project. The problem is the > REPARSE_JDATA_BUFFER struct. I''m just not sure how to set those > members, specifically, the PathBuffer member. The target looks good, > it''s UTF-16LE encoded, but I can''t make it work, despite trying > several ways of defining the struct, and setting various struct > members. > > A quick gist for reference: https://gist.github.com/2721257 > > Help much appreciated! > >The REPARSE_JDATA_BUFFER is a kind of the variable length structure. The actual size of structure is determined by ReparseDataLength member. Here is my trial. # define sufficient size of structure. class REPARSE_JDATA_BUFFER < FFI::Struct layout( :ReparseTag, :ulong, :ReparseDataLength, :ushort, :Reserved, :ushort, :SubstituteNameOffset, :ushort, :SubstituteNameLength, :ushort, :PrintNameOffset, :ushort, :PrintNameLength, :ushort, :PathBuffer, [:char, 1024] ) end # UTF-16LE encoded string target = "\\??\\".encode(''UTF-16LE'') + from_path rdb = REPARSE_JDATA_BUFFER.new rdb[:ReparseTag] = 2684354563 # IO_REPARSE_TAG_MOUNT_POINT rdb[:ReparseDataLength] = target.bytesize + 12 rdb[:Reserved] = 0 rdb[:SubstituteNameOffset] = 0 rdb[:SubstituteNameLength] = target.bytesize rdb[:PrintNameOffset] = target.bytesize + 2 rdb[:PrintNameLength] = 0 rdb[:PathBuffer] = target Regards, Park Heesob -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/win32utils-devel/attachments/20120518/239606e1/attachment.html>
On Thu, May 17, 2012 at 9:44 PM, Heesob Park <phasis at gmail.com> wrote:> Hi, > > 2012/5/18 Daniel Berger <djberg96 at gmail.com> >> >> Hi, >> >> Try as I might, I just cannot get Dir.create_junction to work with FFI >> in the ffi branch of the win32-dir project. The problem is the >> REPARSE_JDATA_BUFFER struct. I''m just not sure how to set those >> members, specifically, the PathBuffer member. The target looks good, >> it''s UTF-16LE encoded, but I can''t make it work, despite trying >> several ways of defining the struct, and setting various struct >> members. >> >> A quick gist for reference: https://gist.github.com/2721257 >> >> Help much appreciated! >> > > The?REPARSE_JDATA_BUFFER? is a kind of ?the variable length structure. > The actual size of structure is determined by?ReparseDataLength member. > > Here is my trial. > > # define sufficient size of structure. > class REPARSE_JDATA_BUFFER < FFI::Struct > ? ? layout( > ? ? ? :ReparseTag, :ulong, > ? ? ? :ReparseDataLength, :ushort, > ? ? ? :Reserved, :ushort, > ? ? ? :SubstituteNameOffset, :ushort, > ? ? ? :SubstituteNameLength, :ushort, > ? ? ? :PrintNameOffset, :ushort, > ? ? ? :PrintNameLength, :ushort, > ? ? ? :PathBuffer, [:char, 1024] > ? ? ) > end > > ?# UTF-16LE encoded string > ? target = "\\??\\".encode(''UTF-16LE'') + from_path > > ? rdb = REPARSE_JDATA_BUFFER.new > ? rdb[:ReparseTag] = 2684354563 # IO_REPARSE_TAG_MOUNT_POINT > ? rdb[:ReparseDataLength] = target.bytesize + 12 > ? rdb[:Reserved] = 0 > ? rdb[:SubstituteNameOffset] = 0 > ? rdb[:SubstituteNameLength] = target.bytesize > ? rdb[:PrintNameOffset] = target.bytesize + 2 > ? rdb[:PrintNameLength] = 0 > ? rdb[:PathBuffer] ?= targetI tried that, but I still got: DeviceIoControl: The data present in the reparse point buffer is invalid. Did it work for you? Regards, Dan
Hi, 2012/5/18 Daniel Berger <djberg96 at gmail.com>> On Thu, May 17, 2012 at 9:44 PM, Heesob Park <phasis at gmail.com> wrote: > > Hi, > > > > 2012/5/18 Daniel Berger <djberg96 at gmail.com> > >> > >> Hi, > >> > >> Try as I might, I just cannot get Dir.create_junction to work with FFI > >> in the ffi branch of the win32-dir project. The problem is the > >> REPARSE_JDATA_BUFFER struct. I''m just not sure how to set those > >> members, specifically, the PathBuffer member. The target looks good, > >> it''s UTF-16LE encoded, but I can''t make it work, despite trying > >> several ways of defining the struct, and setting various struct > >> members. > >> > >> A quick gist for reference: https://gist.github.com/2721257 > >> > >> Help much appreciated! > >> > > > > The REPARSE_JDATA_BUFFER is a kind of the variable length structure. > > The actual size of structure is determined by ReparseDataLength member. > > > > Here is my trial. > > > > # define sufficient size of structure. > > class REPARSE_JDATA_BUFFER < FFI::Struct > > layout( > > :ReparseTag, :ulong, > > :ReparseDataLength, :ushort, > > :Reserved, :ushort, > > :SubstituteNameOffset, :ushort, > > :SubstituteNameLength, :ushort, > > :PrintNameOffset, :ushort, > > :PrintNameLength, :ushort, > > :PathBuffer, [:char, 1024] > > ) > > end > > > > # UTF-16LE encoded string > > target = "\\??\\".encode(''UTF-16LE'') + from_path > > > > rdb = REPARSE_JDATA_BUFFER.new > > rdb[:ReparseTag] = 2684354563 # IO_REPARSE_TAG_MOUNT_POINT > > rdb[:ReparseDataLength] = target.bytesize + 12 > > rdb[:Reserved] = 0 > > rdb[:SubstituteNameOffset] = 0 > > rdb[:SubstituteNameLength] = target.bytesize > > rdb[:PrintNameOffset] = target.bytesize + 2 > > rdb[:PrintNameLength] = 0 > > rdb[:PathBuffer] = target > > I tried that, but I still got: DeviceIoControl: The data present in > the reparse point buffer is invalid. > > Did it work for you? > >Here is a working code. https://gist.github.com/1c431b679b26c947a7d2 Regards, Park Heesob -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/win32utils-devel/attachments/20120518/4dabcc28/attachment.html>
On Fri, May 18, 2012 at 1:35 AM, Heesob Park <phasis at gmail.com> wrote:> Hi, > > 2012/5/18 Daniel Berger <djberg96 at gmail.com> >> >> On Thu, May 17, 2012 at 9:44 PM, Heesob Park <phasis at gmail.com> wrote: >> > Hi, >> > >> > 2012/5/18 Daniel Berger <djberg96 at gmail.com> >> >> >> >> Hi, >> >> >> >> Try as I might, I just cannot get Dir.create_junction to work with FFI >> >> in the ffi branch of the win32-dir project. The problem is the >> >> REPARSE_JDATA_BUFFER struct. I''m just not sure how to set those >> >> members, specifically, the PathBuffer member. The target looks good, >> >> it''s UTF-16LE encoded, but I can''t make it work, despite trying >> >> several ways of defining the struct, and setting various struct >> >> members. >> >> >> >> A quick gist for reference: https://gist.github.com/2721257 >> >> >> >> Help much appreciated! >> >> >> > >> > The?REPARSE_JDATA_BUFFER? is a kind of ?the variable length structure. >> > The actual size of structure is determined by?ReparseDataLength member. >> > >> > Here is my trial. >> > >> > # define sufficient size of structure. >> > class REPARSE_JDATA_BUFFER < FFI::Struct >> > ? ? layout( >> > ? ? ? :ReparseTag, :ulong, >> > ? ? ? :ReparseDataLength, :ushort, >> > ? ? ? :Reserved, :ushort, >> > ? ? ? :SubstituteNameOffset, :ushort, >> > ? ? ? :SubstituteNameLength, :ushort, >> > ? ? ? :PrintNameOffset, :ushort, >> > ? ? ? :PrintNameLength, :ushort, >> > ? ? ? :PathBuffer, [:char, 1024] >> > ? ? ) >> > end >> > >> > ?# UTF-16LE encoded string >> > ? target = "\\??\\".encode(''UTF-16LE'') + from_path >> > >> > ? rdb = REPARSE_JDATA_BUFFER.new >> > ? rdb[:ReparseTag] = 2684354563 # IO_REPARSE_TAG_MOUNT_POINT >> > ? rdb[:ReparseDataLength] = target.bytesize + 12 >> > ? rdb[:Reserved] = 0 >> > ? rdb[:SubstituteNameOffset] = 0 >> > ? rdb[:SubstituteNameLength] = target.bytesize >> > ? rdb[:PrintNameOffset] = target.bytesize + 2 >> > ? rdb[:PrintNameLength] = 0 >> > ? rdb[:PathBuffer] ?= target >> >> I tried that, but I still got: DeviceIoControl: The data present in >> the reparse point buffer is invalid. >> >> Did it work for you? >> > > Here is a working code. > https://gist.github.com/1c431b679b26c947a7d2Excellent, thank you! Wayne Meissner showed me a trick. For PathBuffer,he said I could declare it as "PathBuffer, [:char, 2]" (since it''s really a wchar), and then assign PathBuffer like this: rdb[:PathBuffer].to_ptr.put_bytes(0, target, target.bytesize) However, when I tried that I end up with a "to []" directory as a result and, although it doesn''t raise an error in the code, I can''t actually cd into that directory after it''s created. I also realized there''s a bug (in the original version) in that it never checks if the "from" (2nd) argument actually exists! So, I''ve added that. I''m not sure what it''s doing if there''s nothing for it to junction from. I think I should add an check to make sure the 2nd arg actually exists before proceeding. Why rdb[:ReparseDataLength] + 8? What''s the "+8" for? Thanks again for all your help. Regards, Dan
Hi, Dan 2012/5/19 Daniel Berger <djberg96 at gmail.com>> On Fri, May 18, 2012 at 1:35 AM, Heesob Park <phasis at gmail.com> wrote: > > Hi, > > > > 2012/5/18 Daniel Berger <djberg96 at gmail.com> > >> > >> On Thu, May 17, 2012 at 9:44 PM, Heesob Park <phasis at gmail.com> wrote: > >> > Hi, > >> > > >> > 2012/5/18 Daniel Berger <djberg96 at gmail.com> > >> >> > >> >> Hi, > >> >> > >> >> Try as I might, I just cannot get Dir.create_junction to work with > FFI > >> >> in the ffi branch of the win32-dir project. The problem is the > >> >> REPARSE_JDATA_BUFFER struct. I''m just not sure how to set those > >> >> members, specifically, the PathBuffer member. The target looks good, > >> >> it''s UTF-16LE encoded, but I can''t make it work, despite trying > >> >> several ways of defining the struct, and setting various struct > >> >> members. > >> >> > >> >> A quick gist for reference: https://gist.github.com/2721257 > >> >> > >> >> Help much appreciated! > >> >> > >> > > >> > The REPARSE_JDATA_BUFFER is a kind of the variable length structure. > >> > The actual size of structure is determined by ReparseDataLength > member. > >> > > >> > Here is my trial. > >> > > >> > # define sufficient size of structure. > >> > class REPARSE_JDATA_BUFFER < FFI::Struct > >> > layout( > >> > :ReparseTag, :ulong, > >> > :ReparseDataLength, :ushort, > >> > :Reserved, :ushort, > >> > :SubstituteNameOffset, :ushort, > >> > :SubstituteNameLength, :ushort, > >> > :PrintNameOffset, :ushort, > >> > :PrintNameLength, :ushort, > >> > :PathBuffer, [:char, 1024] > >> > ) > >> > end > >> > > >> > # UTF-16LE encoded string > >> > target = "\\??\\".encode(''UTF-16LE'') + from_path > >> > > >> > rdb = REPARSE_JDATA_BUFFER.new > >> > rdb[:ReparseTag] = 2684354563 # IO_REPARSE_TAG_MOUNT_POINT > >> > rdb[:ReparseDataLength] = target.bytesize + 12 > >> > rdb[:Reserved] = 0 > >> > rdb[:SubstituteNameOffset] = 0 > >> > rdb[:SubstituteNameLength] = target.bytesize > >> > rdb[:PrintNameOffset] = target.bytesize + 2 > >> > rdb[:PrintNameLength] = 0 > >> > rdb[:PathBuffer] = target > >> > >> I tried that, but I still got: DeviceIoControl: The data present in > >> the reparse point buffer is invalid. > >> > >> Did it work for you? > >> > > > > Here is a working code. > > https://gist.github.com/1c431b679b26c947a7d2 > > Excellent, thank you! > > Wayne Meissner showed me a trick. For PathBuffer,he said I could > declare it as "PathBuffer, [:char, 2]" (since it''s really a wchar), > and then assign PathBuffer like this: > > rdb[:PathBuffer].to_ptr.put_bytes(0, target, target.bytesize) > > However, when I tried that I end up with a "to []" directory as a > result and, although it doesn''t raise an error in the code, I can''t > actually cd into that directory after it''s created. > > I also realized there''s a bug (in the original version) in that it > never checks if the "from" (2nd) argument actually exists! So, I''ve > added that. I''m not sure what it''s doing if there''s nothing for it to > junction from. I think I should add an check to make sure the 2nd arg > actually exists before proceeding. > > Why rdb[:ReparseDataLength] + 8? What''s the "+8" for? > >The 8 is called REPARSE_DATA_BUFFER_HEADER_SIZE. It is calculated by sizeof(ReparseTag)+sizeof(ReparseDataLength)+sizeof(Reserved).> Thanks again for all your help. > > It''s my pleasure to help you.Regards, Park Heesob -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/win32utils-devel/attachments/20120519/9ac1e2e5/attachment.html>
On Fri, May 18, 2012 at 9:52 AM, Heesob Park <phasis at gmail.com> wrote:> Hi, Dan > > 2012/5/19 Daniel Berger <djberg96 at gmail.com> >> >> On Fri, May 18, 2012 at 1:35 AM, Heesob Park <phasis at gmail.com> wrote: >> > Hi, >> > >> > 2012/5/18 Daniel Berger <djberg96 at gmail.com> >> >> >> >> On Thu, May 17, 2012 at 9:44 PM, Heesob Park <phasis at gmail.com> wrote: >> >> > Hi, >> >> > >> >> > 2012/5/18 Daniel Berger <djberg96 at gmail.com> >> >> >> >> >> >> Hi, >> >> >> >> >> >> Try as I might, I just cannot get Dir.create_junction to work with >> >> >> FFI >> >> >> in the ffi branch of the win32-dir project. The problem is the >> >> >> REPARSE_JDATA_BUFFER struct. I''m just not sure how to set those >> >> >> members, specifically, the PathBuffer member. The target looks good, >> >> >> it''s UTF-16LE encoded, but I can''t make it work, despite trying >> >> >> several ways of defining the struct, and setting various struct >> >> >> members. >> >> >> >> >> >> A quick gist for reference: https://gist.github.com/2721257 >> >> >> >> >> >> Help much appreciated! >> >> >> >> >> > >> >> > The?REPARSE_JDATA_BUFFER? is a kind of ?the variable length >> >> > structure. >> >> > The actual size of structure is determined by?ReparseDataLength >> >> > member. >> >> > >> >> > Here is my trial. >> >> > >> >> > # define sufficient size of structure. >> >> > class REPARSE_JDATA_BUFFER < FFI::Struct >> >> > ? ? layout( >> >> > ? ? ? :ReparseTag, :ulong, >> >> > ? ? ? :ReparseDataLength, :ushort, >> >> > ? ? ? :Reserved, :ushort, >> >> > ? ? ? :SubstituteNameOffset, :ushort, >> >> > ? ? ? :SubstituteNameLength, :ushort, >> >> > ? ? ? :PrintNameOffset, :ushort, >> >> > ? ? ? :PrintNameLength, :ushort, >> >> > ? ? ? :PathBuffer, [:char, 1024] >> >> > ? ? ) >> >> > end >> >> > >> >> > ?# UTF-16LE encoded string >> >> > ? target = "\\??\\".encode(''UTF-16LE'') + from_path >> >> > >> >> > ? rdb = REPARSE_JDATA_BUFFER.new >> >> > ? rdb[:ReparseTag] = 2684354563 # IO_REPARSE_TAG_MOUNT_POINT >> >> > ? rdb[:ReparseDataLength] = target.bytesize + 12 >> >> > ? rdb[:Reserved] = 0 >> >> > ? rdb[:SubstituteNameOffset] = 0 >> >> > ? rdb[:SubstituteNameLength] = target.bytesize >> >> > ? rdb[:PrintNameOffset] = target.bytesize + 2 >> >> > ? rdb[:PrintNameLength] = 0 >> >> > ? rdb[:PathBuffer] ?= target >> >> >> >> I tried that, but I still got: DeviceIoControl: The data present in >> >> the reparse point buffer is invalid. >> >> >> >> Did it work for you? >> >> >> > >> > Here is a working code. >> > https://gist.github.com/1c431b679b26c947a7d2 >> >> Excellent, thank you! >> >> Wayne Meissner showed me a trick. For PathBuffer,he said I could >> declare it as "PathBuffer, [:char, 2]" (since it''s really a wchar), >> and then assign PathBuffer like this: >> >> rdb[:PathBuffer].to_ptr.put_bytes(0, target, target.bytesize) >> >> However, when I tried that I end up with a "to []" directory as a >> result and, although it doesn''t raise an error in the code, I can''t >> actually cd into that directory after it''s created. >> >> I also realized there''s a bug (in the original version) in that it >> never checks if the "from" (2nd) argument actually exists! So, I''ve >> added that. I''m not sure what it''s doing if there''s nothing for it to >> junction from. I think I should add an check to make sure the 2nd arg >> actually exists before proceeding. >> >> Why rdb[:ReparseDataLength] + 8? What''s the "+8" for? >> > > The 8 is called REPARSE_DATA_BUFFER_HEADER_SIZE. > It is calculated by > sizeof(ReparseTag)+sizeof(ReparseDataLength)+sizeof(Reserved). > >> >> Thanks again for all your help. >> > It''s my pleasure to help you.Ok, thanks. I guess I thought that was baked into the rdb.size. Any idea why the .to_ptr.put_bytes approach gives strange results? Regards, Dan
> Ok, thanks. I guess I thought that was baked into the rdb.size. > > Any idea why the .to_ptr.put_bytes approach gives strange results?Hm, think it''s because it''s a CharArray instead of a String. I''m not sure how to make it a string yet. Looking into it. Dan