Windows: hardlink support is broken on shared drives
Adrian Buehlmann
adrian at cadifra.com
Mon Aug 23 18:09:45 CDT 2010
On 24.08.2010 00:44, Adrian Buehlmann wrote:
> On 24.08.2010 00:17, Adrian Buehlmann wrote:
>> (adding Patrick to cc)
>>
>> On 23.08.2010 22:22, Gavin Erry wrote:
>>> All
>>>
>>>
>>>
>>> I’ve been reading this thread with interest since I posted the problem
>>> on the discussion list. Thanks for the fix – I will test it in the next
>>> build of Hg. It seemed strange that GetFileInformationByHandle doesn’t
>>> work too well so I had a look (in C++ though)
>>>
>>>
>>>
>>> It seems that you can get different results depending on how the handle
>>> was created with the CreateFile function.
>>>
>>> If I use GENERIC_READ or FILE_GENERIC_READ for the desired access in
>>> CreateFile then I get an incorrect hardlink count.
>>>
>>> Using FILE_READ_ATTRIBUTES | SYNCHRONIZE (which is a subset of
>>> FILE_GENERIC_READ) then I get the correct hardlink count over the network.
>>>
>>>
>>>
>>> This is all with Windows XP, and MS C++ (I don’t do Python).
>>>
>>>
>>>
>>> This is really a FYI - I have a bit of C++ code if anyone is interested,
>>> but am not sure of the posting policy.
>>>
>>>
>>>
>>> Gavin
>>
>> Very interesting! Thanks.
>>
>> I've modified Patrick's testlink.py accordingly (attached). Specifically
>> I changed _getfileinfo to (the symbolic constants for FILE_READ_ATTRIBUTES
>> 0x0080 and SYNCHRONIZE 0x00100000L were missing in win32file):
>>
>> def _getfileinfo(pathname):
>> """Return number of hardlinks for the given file."""
>> try:
>> fh = win32file.CreateFile(pathname,
>> 0x0080 | 0x00100000L,
>> win32file.FILE_SHARE_READ,
>> None, win32file.OPEN_EXISTING, 0, None)
>> try:
>> return win32file.GetFileInformationByHandle(fh)
>> finally:
>> fh.Close()
>> except pywintypes.error, e:
>> print e
>> return None
>
> Even simpler. Just specifying 0 for dwDesiredAccess works as well:
>
> def _getfileinfo(pathname):
> """Return number of hardlinks for the given file."""
> try:
> fh = win32file.CreateFile(pathname,
> 0, # device query access
> win32file.FILE_SHARE_READ,
> None, win32file.OPEN_EXISTING, 0, None)
> try:
> return win32file.GetFileInformationByHandle(fh)
> finally:
> fh.Close()
> except pywintypes.error, e:
> print e
> return None
>
>
> [1] has '0' for desiredAccess as (quote):
>
> "Specifies device query access to the object. An application can query device
> attributes without accessing the device."
>
> [1] http://docs.activestate.com/activepython/2.5/pywin32/win32file__CreateFile_meth.html
I found 0 for desiredAccess in MSDN documented as [2]:
"If this parameter is zero, the application can query certain metadata
such as file, directory, or device attributes without accessing that
file or device, even if GENERIC_READ access would have been denied. "
[2] http://msdn.microsoft.com/en-us/library/aa363858%28VS.85%29.aspx
More information about the Mercurial-devel
mailing list