// File: demon386[P]git-store/./libs/filesystem/src/operations.cpp
// Function: boost::filesystem::detail::equivalent(boost::filesystem::path const&, boost::filesystem::path const&, boost::system::error_code*)
BOOST_FILESYSTEM_DECL
  bool equivalent(const path& p1, const path& p2, system::error_code* ec)
  {
#   ifdef BOOST_POSIX_API
    struct stat s2;
    int e2(::stat(p2.c_str(), &s2));
    struct stat s1;
    int e1(::stat(p1.c_str(), &s1));

    if (e1 != 0 || e2 != 0)
    {
      // if one is invalid and the other isn't then they aren't equivalent,
      // but if both are invalid then it is an error
      error (e1 != 0 && e2 != 0, p1, p2, ec, "boost::filesystem::equivalent");
      return false;
    }

    // both stats now known to be valid
    return  s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino
        // According to the POSIX stat specs, "The st_ino and st_dev fields
        // taken together uniquely identify the file within the system."
        // Just to be sure, size and mod time are also checked.
        && s1.st_size == s2.st_size && s1.st_mtime == s2.st_mtime;

#   else  // Windows

    // Note well: Physical location on external media is part of the
    // equivalence criteria. If there are no open handles, physical location
    // can change due to defragmentation or other relocations. Thus handles
    // must be held open until location information for both paths has
    // been retrieved.

    // p2 is done first, so any error reported is for p1
    handle_wrapper h2(
      create_file_handle(
          p2.c_str(),
          0,
          FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
          0,
          OPEN_EXISTING,
          FILE_FLAG_BACKUP_SEMANTICS,
          0));

    handle_wrapper h1(
      create_file_handle(
          p1.c_str(),
          0,
          FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
          0,
          OPEN_EXISTING,
          FILE_FLAG_BACKUP_SEMANTICS,
          0));

    if (h1.handle == INVALID_HANDLE_VALUE
      || h2.handle == INVALID_HANDLE_VALUE)
    {
      // if one is invalid and the other isn't, then they aren't equivalent,
      // but if both are invalid then it is an error
      error((h1.handle == INVALID_HANDLE_VALUE
        && h2.handle == INVALID_HANDLE_VALUE) ? BOOST_ERROR_NOT_SUPPORTED : 0, p1, p2, ec,
          "boost::filesystem::equivalent");
      return false;
    }

    // at this point, both handles are known to be valid

    BY_HANDLE_FILE_INFORMATION info1, info2;

    if (error(!::GetFileInformationByHandle(h1.handle, &info1) ? BOOST_ERRNO : 0,
      p1, p2, ec, "boost::filesystem::equivalent"))
        return  false;

    if (error(!::GetFileInformationByHandle(h2.handle, &info2) ? BOOST_ERRNO : 0,
      p1, p2, ec, "boost::filesystem::equivalent"))
        return  false;

    // In theory, volume serial numbers are sufficient to distinguish between
    // devices, but in practice VSN's are sometimes duplicated, so last write
    // time and file size are also checked.
      return 
        info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber
        && info1.nFileIndexHigh == info2.nFileIndexHigh
        && info1.nFileIndexLow == info2.nFileIndexLow
        && info1.nFileSizeHigh == info2.nFileSizeHigh
        && info1.nFileSizeLow == info2.nFileSizeLow
        && info1.ftLastWriteTime.dwLowDateTime
          == info2.ftLastWriteTime.dwLowDateTime
        && info1.ftLastWriteTime.dwHighDateTime
          == info2.ftLastWriteTime.dwHighDateTime;

#   endif
  }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1b0, %rsp            # imm = 0x1B0
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x18(%rbp), %rdi
callq 0x4dc70
movq %rax, %rdi
leaq -0xb0(%rbp), %rsi
callq 0xdae0
movl %eax, -0xb4(%rbp)
movq -0x10(%rbp), %rdi
callq 0x4dc70
movq %rax, %rdi
leaq -0x148(%rbp), %rsi
callq 0xdae0
movl %eax, -0x14c(%rbp)
cmpl $0x0, -0x14c(%rbp)
jne 0x4a1f9
cmpl $0x0, -0xb4(%rbp)
je 0x4a306
xorl %eax, %eax
cmpl $0x0, -0x14c(%rbp)
movb %al, -0x185(%rbp)
je 0x4a21a
cmpl $0x0, -0xb4(%rbp)
setne %al
movb %al, -0x185(%rbp)
movb -0x185(%rbp), %al
movzbl %al, %eax
andl $0x1, %eax
movl %eax, -0x1ac(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1a8(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x1a0(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x198(%rbp)
leaq -0x171(%rbp), %rdi
movq %rdi, -0x190(%rbp)
callq 0xdb50
movq -0x190(%rbp), %rdx
leaq 0x18b21(%rip), %rsi     # 0x62d8f
leaq -0x170(%rbp), %rdi
callq 0xd8b0
jmp 0x4a27c
movq -0x198(%rbp), %rcx
movq -0x1a0(%rbp), %rdx
movq -0x1a8(%rbp), %rsi
movl -0x1ac(%rbp), %edi
leaq -0x170(%rbp), %r8
callq 0x48dd0
jmp 0x4a2a5
leaq -0x170(%rbp), %rdi
callq 0xdca8
leaq -0x171(%rbp), %rdi
callq 0xd6b0
movb $0x0, -0x1(%rbp)
jmp 0x4a36a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x180(%rbp)
movl %eax, -0x184(%rbp)
jmp 0x4a2f8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x180(%rbp)
movl %eax, -0x184(%rbp)
leaq -0x170(%rbp), %rdi
callq 0xdca8
leaq -0x171(%rbp), %rdi
callq 0xd6b0
jmp 0x4a378
movq -0x148(%rbp), %rcx
xorl %eax, %eax
cmpq -0xb0(%rbp), %rcx
movb %al, -0x1ad(%rbp)
jne 0x4a35f
movq -0x140(%rbp), %rcx
xorl %eax, %eax
cmpq -0xa8(%rbp), %rcx
movb %al, -0x1ad(%rbp)
jne 0x4a35f
movq -0x118(%rbp), %rcx
xorl %eax, %eax
cmpq -0x80(%rbp), %rcx
movb %al, -0x1ad(%rbp)
jne 0x4a35f
movq -0xf0(%rbp), %rax
cmpq -0x58(%rbp), %rax
sete %al
movb %al, -0x1ad(%rbp)
movb -0x1ad(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x1b0, %rsp            # imm = 0x1B0
popq %rbp
retq
movq -0x180(%rbp), %rdi
callq 0xdb30
nopw %cs:(%rax,%rax)