Пример #1
0
bool
tr_sys_path_is_same (const char  * path1,
                     const char  * path2,
                     tr_error   ** error)
{
  bool ret = false;
  wchar_t * wide_path1 = NULL;
  wchar_t * wide_path2 = NULL;
  HANDLE handle1 = INVALID_HANDLE_VALUE;
  HANDLE handle2 = INVALID_HANDLE_VALUE;
  BY_HANDLE_FILE_INFORMATION fi1, fi2;

  assert (path1 != NULL);
  assert (path2 != NULL);

  wide_path1 = path_to_native_path (path1);
  if (wide_path1 == NULL)
    goto fail;

  wide_path2 = path_to_native_path (path2);
  if (wide_path2 == NULL)
    goto fail;

  handle1 = CreateFileW (wide_path1, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
  if (handle1 == INVALID_HANDLE_VALUE)
    goto fail;

  handle2 = CreateFileW (wide_path2, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
  if (handle2 == INVALID_HANDLE_VALUE)
    goto fail;

  /* TODO: Use GetFileInformationByHandleEx on >= Server 2012 */

  if (!GetFileInformationByHandle (handle1, &fi1) || !GetFileInformationByHandle (handle2, &fi2))
    goto fail;

  ret = fi1.dwVolumeSerialNumber == fi2.dwVolumeSerialNumber &&
        fi1.nFileIndexHigh == fi2.nFileIndexHigh &&
        fi1.nFileIndexLow  == fi2.nFileIndexLow;

  goto cleanup;

fail:
  set_system_error_if_file_found (error, GetLastError ());

cleanup:
  CloseHandle (handle2);
  CloseHandle (handle1);

  tr_free (wide_path2);
  tr_free (wide_path1);

  return ret;
}
Пример #2
0
bool
tr_sys_path_remove (const char  * path,
                    tr_error   ** error)
{
  bool ret = false;
  wchar_t * wide_path;

  assert (path != NULL);

  wide_path = path_to_native_path (path);

  if (wide_path != NULL)
    {
      const DWORD attributes = GetFileAttributesW (wide_path);

      if (attributes != INVALID_FILE_ATTRIBUTES)
        {
          if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
            ret = RemoveDirectoryW (wide_path);
          else
            ret = DeleteFileW (wide_path);
        }
    }

  if (!ret)
    set_system_error (error, GetLastError ());

  tr_free (wide_path);

  return ret;
}
Пример #3
0
static tr_sys_file_t
open_file (const char  * path,
           DWORD         access,
           DWORD         disposition,
           DWORD         flags,
           tr_error   ** error)
{
  tr_sys_file_t ret = TR_BAD_SYS_FILE;
  wchar_t * wide_path;

  assert (path != NULL);

  wide_path = path_to_native_path (path);

  if (wide_path != NULL)
    ret = CreateFileW (wide_path, access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                       NULL, disposition, flags, NULL);

  if (ret == TR_BAD_SYS_FILE)
    set_system_error (error, GetLastError ());

  tr_free (wide_path);

  return ret;
}
Пример #4
0
bool tr_sys_path_remove(char const* path, tr_error** error)
{
    TR_ASSERT(path != NULL);

    bool ret = false;
    wchar_t* wide_path = path_to_native_path(path);

    if (wide_path != NULL)
    {
        DWORD const attributes = GetFileAttributesW(wide_path);

        if (attributes != INVALID_FILE_ATTRIBUTES)
        {
            if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
            {
                ret = RemoveDirectoryW(wide_path);
            }
            else
            {
                ret = DeleteFileW(wide_path);
            }
        }
    }

    if (!ret)
    {
        set_system_error(error, GetLastError());
    }

    tr_free(wide_path);

    return ret;
}
Пример #5
0
bool tr_sys_path_get_info(char const* path, int flags, tr_sys_path_info* info, tr_error** error)
{
    TR_ASSERT(path != NULL);
    TR_ASSERT(info != NULL);

    bool ret = false;
    wchar_t* wide_path = path_to_native_path(path);

    if ((flags & TR_SYS_PATH_NO_FOLLOW) == 0)
    {
        HANDLE handle = INVALID_HANDLE_VALUE;

        if (wide_path != NULL)
        {
            handle = CreateFileW(wide_path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
        }

        if (handle != INVALID_HANDLE_VALUE)
        {
            tr_error* my_error = NULL;
            ret = tr_sys_file_get_info(handle, info, &my_error);

            if (!ret)
            {
                tr_error_propagate(error, &my_error);
            }

            CloseHandle(handle);
        }
        else
        {
            set_system_error(error, GetLastError());
        }
    }
    else
    {
        WIN32_FILE_ATTRIBUTE_DATA attributes;

        if (wide_path != NULL)
        {
            ret = GetFileAttributesExW(wide_path, GetFileExInfoStandard, &attributes);
        }

        if (ret)
        {
            stat_to_sys_path_info(attributes.dwFileAttributes, attributes.nFileSizeLow, attributes.nFileSizeHigh,
                &attributes.ftLastWriteTime, info);
        }
        else
        {
            set_system_error(error, GetLastError());
        }
    }

    tr_free(wide_path);

    return ret;
}
Пример #6
0
bool
tr_sys_path_rename (const char  * src_path,
                    const char  * dst_path,
                    tr_error   ** error)
{
  bool ret = false;
  wchar_t * wide_src_path;
  wchar_t * wide_dst_path;

  assert (src_path != NULL);
  assert (dst_path != NULL);

  wide_src_path = path_to_native_path (src_path);
  wide_dst_path = path_to_native_path (dst_path);

  if (wide_src_path != NULL && wide_dst_path != NULL)
    {
      DWORD flags = MOVEFILE_REPLACE_EXISTING;
      DWORD attributes;

      attributes = GetFileAttributesW (wide_src_path);
      if (attributes != INVALID_FILE_ATTRIBUTES &&
          (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
        {
          flags = 0;
        }
      else
        {
          attributes = GetFileAttributesW (wide_dst_path);
          if (attributes != INVALID_FILE_ATTRIBUTES &&
              (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
            flags = 0;
        }

      ret = MoveFileExW (wide_src_path, wide_dst_path, flags);
    }

  if (!ret)
    set_system_error (error, GetLastError ());

  tr_free (wide_dst_path);
  tr_free (wide_src_path);

  return ret;
}
Пример #7
0
char *
tr_sys_path_resolve (const char  * path,
                     tr_error   ** error)
{
  char * ret = NULL;
  wchar_t * wide_path;
  wchar_t * wide_ret = NULL;
  HANDLE handle = INVALID_HANDLE_VALUE;
  DWORD wide_ret_size;

  assert (path != NULL);

  wide_path = path_to_native_path (path);
  if (wide_path == NULL)
    goto fail;

  handle = CreateFileW (wide_path, FILE_READ_EA,
                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                        NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
  if (handle == INVALID_HANDLE_VALUE)
    goto fail;

  wide_ret_size = GetFinalPathNameByHandleW (handle, NULL, 0, 0);
  if (wide_ret_size == 0)
    goto fail;

  wide_ret = tr_new (wchar_t, wide_ret_size);
  if (GetFinalPathNameByHandleW (handle, wide_ret, wide_ret_size, 0) != wide_ret_size - 1)
    goto fail;

  /* Resolved path always begins with "\\?\", so skip those first four chars. */
  ret = tr_win32_native_to_utf8 (wide_ret + 4, -1);
  if (ret != NULL)
    goto cleanup;

fail:
  set_system_error (error, GetLastError ());

  tr_free (ret);
  ret = NULL;

cleanup:
  tr_free (wide_ret);
  tr_free (wide_path);

  if (handle != INVALID_HANDLE_VALUE)
    CloseHandle (handle);

  return ret;
}
Пример #8
0
static bool create_dir(char const* path, int flags, int permissions, bool okay_if_exists, tr_error** error)
{
    TR_ASSERT(path != NULL);

    (void)permissions;

    bool ret;
    DWORD error_code = ERROR_SUCCESS;
    wchar_t* wide_path = path_to_native_path(path);

    if ((flags & TR_SYS_DIR_CREATE_PARENTS) != 0)
    {
        error_code = SHCreateDirectoryExW(NULL, wide_path, NULL);
        ret = error_code == ERROR_SUCCESS;
    }
    else
    {
        ret = CreateDirectoryW(wide_path, NULL);

        if (!ret)
        {
            error_code = GetLastError();
        }
    }

    if (!ret && error_code == ERROR_ALREADY_EXISTS && okay_if_exists)
    {
        DWORD const attributes = GetFileAttributesW(wide_path);

        if (attributes != INVALID_FILE_ATTRIBUTES &&
            (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
        {
            ret = true;
        }
    }

    if (!ret)
    {
        set_system_error(error, error_code);
    }

    tr_free(wide_path);

    return ret;
}
Пример #9
0
bool
tr_sys_path_exists (const char  * path,
                    tr_error   ** error)
{
  bool ret = false;
  wchar_t * wide_path;
  HANDLE handle = INVALID_HANDLE_VALUE;

  assert (path != NULL);

  wide_path = path_to_native_path (path);

  if (wide_path != NULL)
    {
      DWORD attributes = GetFileAttributesW (wide_path);
      if (attributes != INVALID_FILE_ATTRIBUTES)
        {
          if (attributes & FILE_ATTRIBUTE_REPARSE_POINT)
            {
              handle = CreateFileW (wide_path, 0, 0, NULL, OPEN_EXISTING,
                                    FILE_FLAG_BACKUP_SEMANTICS, NULL);

              ret = handle != INVALID_HANDLE_VALUE;
            }
          else
            {
              ret = true;
            }
        }
    }

  if (!ret)
    set_system_error_if_file_found (error, GetLastError ());

  if (handle != INVALID_HANDLE_VALUE)
    CloseHandle (handle);

  tr_free (wide_path);

  return ret;
}