mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-23 20:46:14 +01:00
Merge branch 'w32-gfileinfo-improvements' into 'master'
W32 GFileInfo improvements See merge request GNOME/glib!238
This commit is contained in:
commit
cf4ea5ef75
@ -85,6 +85,8 @@
|
|||||||
#define G_FILE_ATTRIBUTE_ID_UNIX_IS_MOUNTPOINT (7340032 + 10)
|
#define G_FILE_ATTRIBUTE_ID_UNIX_IS_MOUNTPOINT (7340032 + 10)
|
||||||
#define G_FILE_ATTRIBUTE_ID_DOS_IS_ARCHIVE (8388608 + 1)
|
#define G_FILE_ATTRIBUTE_ID_DOS_IS_ARCHIVE (8388608 + 1)
|
||||||
#define G_FILE_ATTRIBUTE_ID_DOS_IS_SYSTEM (8388608 + 2)
|
#define G_FILE_ATTRIBUTE_ID_DOS_IS_SYSTEM (8388608 + 2)
|
||||||
|
#define G_FILE_ATTRIBUTE_ID_DOS_IS_MOUNTPOINT (8388608 + 3)
|
||||||
|
#define G_FILE_ATTRIBUTE_ID_DOS_REPARSE_POINT_TAG (8388608 + 4)
|
||||||
#define G_FILE_ATTRIBUTE_ID_OWNER_USER (9437184 + 1)
|
#define G_FILE_ATTRIBUTE_ID_OWNER_USER (9437184 + 1)
|
||||||
#define G_FILE_ATTRIBUTE_ID_OWNER_USER_REAL (9437184 + 2)
|
#define G_FILE_ATTRIBUTE_ID_OWNER_USER_REAL (9437184 + 2)
|
||||||
#define G_FILE_ATTRIBUTE_ID_OWNER_GROUP (9437184 + 3)
|
#define G_FILE_ATTRIBUTE_ID_OWNER_GROUP (9437184 + 3)
|
||||||
|
@ -245,6 +245,8 @@ ensure_attribute_hash (void)
|
|||||||
REGISTER_ATTRIBUTE (UNIX_IS_MOUNTPOINT);
|
REGISTER_ATTRIBUTE (UNIX_IS_MOUNTPOINT);
|
||||||
REGISTER_ATTRIBUTE (DOS_IS_ARCHIVE);
|
REGISTER_ATTRIBUTE (DOS_IS_ARCHIVE);
|
||||||
REGISTER_ATTRIBUTE (DOS_IS_SYSTEM);
|
REGISTER_ATTRIBUTE (DOS_IS_SYSTEM);
|
||||||
|
REGISTER_ATTRIBUTE (DOS_IS_MOUNTPOINT);
|
||||||
|
REGISTER_ATTRIBUTE (DOS_REPARSE_POINT_TAG);
|
||||||
REGISTER_ATTRIBUTE (OWNER_USER);
|
REGISTER_ATTRIBUTE (OWNER_USER);
|
||||||
REGISTER_ATTRIBUTE (OWNER_USER_REAL);
|
REGISTER_ATTRIBUTE (OWNER_USER_REAL);
|
||||||
REGISTER_ATTRIBUTE (OWNER_GROUP);
|
REGISTER_ATTRIBUTE (OWNER_GROUP);
|
||||||
|
@ -672,6 +672,33 @@ typedef struct _GFileInfoClass GFileInfoClass;
|
|||||||
**/
|
**/
|
||||||
#define G_FILE_ATTRIBUTE_DOS_IS_SYSTEM "dos::is-system" /* boolean */
|
#define G_FILE_ATTRIBUTE_DOS_IS_SYSTEM "dos::is-system" /* boolean */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT:
|
||||||
|
*
|
||||||
|
* A key in the "dos" namespace for checking if the file is a NTFS mount point
|
||||||
|
* (a volume mount or a junction point).
|
||||||
|
* This attribute is %TRUE if file is a reparse point of type
|
||||||
|
* [IO_REPARSE_TAG_MOUNT_POINT](https://msdn.microsoft.com/en-us/library/dd541667.aspx).
|
||||||
|
* This attribute is only available for DOS file systems.
|
||||||
|
* Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN.
|
||||||
|
*
|
||||||
|
* Since: 2.60
|
||||||
|
**/
|
||||||
|
#define G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT "dos::is-mountpoint" /* boolean */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG:
|
||||||
|
*
|
||||||
|
* A key in the "dos" namespace for getting the file NTFS reparse tag.
|
||||||
|
* This value is 0 for files that are not reparse points.
|
||||||
|
* See the [Reparse Tags](https://msdn.microsoft.com/en-us/library/dd541667.aspx)
|
||||||
|
* page for possible reparse tag values. Corresponding #GFileAttributeType
|
||||||
|
* is %G_FILE_ATTRIBUTE_TYPE_UINT32.
|
||||||
|
*
|
||||||
|
* Since: 2.60
|
||||||
|
**/
|
||||||
|
#define G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG "dos::reparse-point-tag" /* uint32 */
|
||||||
|
|
||||||
/* Owner attributes */
|
/* Owner attributes */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1867,6 +1867,12 @@ _g_local_file_info_get (const char *basename,
|
|||||||
|
|
||||||
if (statbuf.attributes & FILE_ATTRIBUTE_SYSTEM)
|
if (statbuf.attributes & FILE_ATTRIBUTE_SYSTEM)
|
||||||
_g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_DOS_IS_SYSTEM, TRUE);
|
_g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_DOS_IS_SYSTEM, TRUE);
|
||||||
|
|
||||||
|
if (statbuf.reparse_tag == IO_REPARSE_TAG_MOUNT_POINT)
|
||||||
|
_g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_DOS_IS_MOUNTPOINT, TRUE);
|
||||||
|
|
||||||
|
if (statbuf.reparse_tag != 0)
|
||||||
|
_g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_DOS_REPARSE_POINT_TAG, statbuf.reparse_tag);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
symlink_target = NULL;
|
symlink_target = NULL;
|
||||||
|
@ -180,16 +180,24 @@ test_internal_enhanced_stdio (void)
|
|||||||
gchar *programdata;
|
gchar *programdata;
|
||||||
gchar *users_dir;
|
gchar *users_dir;
|
||||||
gchar *allusers;
|
gchar *allusers;
|
||||||
GFile *gf_programdata, *gf_allusers;
|
gchar *commondata;
|
||||||
GFileInfo *fi_programdata, *fi_allusers, *fi_allusers_target;
|
GFile *gf_programdata, *gf_allusers, *gf_commondata;
|
||||||
|
GFileInfo *fi_programdata, *fi_allusers, *fi_allusers_target, *fi_commondata, *fi_commondata_target;
|
||||||
GFileType ft_allusers;
|
GFileType ft_allusers;
|
||||||
GFileType ft_allusers_target;
|
GFileType ft_allusers_target;
|
||||||
GFileType ft_programdata;
|
GFileType ft_programdata;
|
||||||
|
GFileType ft_commondata;
|
||||||
gboolean allusers_is_symlink;
|
gboolean allusers_is_symlink;
|
||||||
|
gboolean commondata_is_symlink;
|
||||||
|
gboolean commondata_is_mount_point;
|
||||||
|
guint32 allusers_reparse_tag;
|
||||||
|
guint32 commondata_reparse_tag;
|
||||||
const gchar *id_allusers;
|
const gchar *id_allusers;
|
||||||
const gchar *id_allusers_target;
|
const gchar *id_allusers_target;
|
||||||
|
const gchar *id_commondata_target;
|
||||||
const gchar *id_programdata;
|
const gchar *id_programdata;
|
||||||
const gchar *allusers_target;
|
const gchar *allusers_target;
|
||||||
|
const gchar *commondata_target;
|
||||||
|
|
||||||
/* C:/ProgramData */
|
/* C:/ProgramData */
|
||||||
programdata = g_utf16_to_utf8 (programdata_dir_w, -1, NULL, NULL, NULL);
|
programdata = g_utf16_to_utf8 (programdata_dir_w, -1, NULL, NULL, NULL);
|
||||||
@ -201,7 +209,11 @@ test_internal_enhanced_stdio (void)
|
|||||||
* for "C:/ProgramData".
|
* for "C:/ProgramData".
|
||||||
*/
|
*/
|
||||||
allusers = g_build_filename (users_dir, "All Users", NULL);
|
allusers = g_build_filename (users_dir, "All Users", NULL);
|
||||||
g_assert_nonnull (allusers);
|
|
||||||
|
/* "C:/Users/All Users/Application Data" is a known
|
||||||
|
* junction for "C:/ProgramData"
|
||||||
|
*/
|
||||||
|
commondata = g_build_filename (allusers, "Application Data", NULL);
|
||||||
|
|
||||||
/* We don't test g_stat() and g_lstat() on these directories,
|
/* We don't test g_stat() and g_lstat() on these directories,
|
||||||
* because it is pointless - there's no way to tell that these
|
* because it is pointless - there's no way to tell that these
|
||||||
@ -213,6 +225,7 @@ test_internal_enhanced_stdio (void)
|
|||||||
*/
|
*/
|
||||||
gf_programdata = g_file_new_for_path (programdata);
|
gf_programdata = g_file_new_for_path (programdata);
|
||||||
gf_allusers = g_file_new_for_path (allusers);
|
gf_allusers = g_file_new_for_path (allusers);
|
||||||
|
gf_commondata = g_file_new_for_path (commondata);
|
||||||
|
|
||||||
fi_programdata = g_file_query_info (gf_programdata,
|
fi_programdata = g_file_query_info (gf_programdata,
|
||||||
G_FILE_ATTRIBUTE_ID_FILE ","
|
G_FILE_ATTRIBUTE_ID_FILE ","
|
||||||
@ -229,52 +242,99 @@ test_internal_enhanced_stdio (void)
|
|||||||
fi_allusers = g_file_query_info (gf_allusers,
|
fi_allusers = g_file_query_info (gf_allusers,
|
||||||
G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET ","
|
G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET ","
|
||||||
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ","
|
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ","
|
||||||
|
G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG ","
|
||||||
G_FILE_ATTRIBUTE_ID_FILE ","
|
G_FILE_ATTRIBUTE_ID_FILE ","
|
||||||
G_FILE_ATTRIBUTE_STANDARD_TYPE,
|
G_FILE_ATTRIBUTE_STANDARD_TYPE,
|
||||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
g_assert (g_file_info_has_attribute (fi_programdata, G_FILE_ATTRIBUTE_ID_FILE));
|
fi_commondata = g_file_query_info (gf_commondata,
|
||||||
g_assert (g_file_info_has_attribute (fi_programdata, G_FILE_ATTRIBUTE_STANDARD_TYPE));
|
G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET ","
|
||||||
|
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ","
|
||||||
|
G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT ","
|
||||||
|
G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG ","
|
||||||
|
G_FILE_ATTRIBUTE_ID_FILE ","
|
||||||
|
G_FILE_ATTRIBUTE_STANDARD_TYPE,
|
||||||
|
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
g_assert (g_file_info_has_attribute (fi_allusers_target, G_FILE_ATTRIBUTE_ID_FILE));
|
fi_commondata_target = g_file_query_info (gf_commondata,
|
||||||
g_assert (g_file_info_has_attribute (fi_allusers_target, G_FILE_ATTRIBUTE_STANDARD_TYPE));
|
G_FILE_ATTRIBUTE_ID_FILE ","
|
||||||
|
G_FILE_ATTRIBUTE_STANDARD_TYPE,
|
||||||
|
G_FILE_QUERY_INFO_NONE,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
g_assert (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_ID_FILE));
|
g_assert_true (g_file_info_has_attribute (fi_programdata, G_FILE_ATTRIBUTE_ID_FILE));
|
||||||
g_assert (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_TYPE));
|
g_assert_true (g_file_info_has_attribute (fi_programdata, G_FILE_ATTRIBUTE_STANDARD_TYPE));
|
||||||
g_assert (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK));
|
|
||||||
g_assert (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET));
|
g_assert_true (g_file_info_has_attribute (fi_allusers_target, G_FILE_ATTRIBUTE_ID_FILE));
|
||||||
|
g_assert_true (g_file_info_has_attribute (fi_allusers_target, G_FILE_ATTRIBUTE_STANDARD_TYPE));
|
||||||
|
g_assert_true (g_file_info_has_attribute (fi_commondata_target, G_FILE_ATTRIBUTE_ID_FILE));
|
||||||
|
g_assert_true (g_file_info_has_attribute (fi_commondata_target, G_FILE_ATTRIBUTE_STANDARD_TYPE));
|
||||||
|
|
||||||
|
g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_ID_FILE));
|
||||||
|
g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_TYPE));
|
||||||
|
g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK));
|
||||||
|
g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG));
|
||||||
|
g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET));
|
||||||
|
|
||||||
|
g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_ID_FILE));
|
||||||
|
g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_TYPE));
|
||||||
|
g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK));
|
||||||
|
g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT));
|
||||||
|
g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG));
|
||||||
|
g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET));
|
||||||
|
|
||||||
ft_allusers = g_file_info_get_file_type (fi_allusers);
|
ft_allusers = g_file_info_get_file_type (fi_allusers);
|
||||||
ft_allusers_target = g_file_info_get_file_type (fi_allusers_target);
|
ft_allusers_target = g_file_info_get_file_type (fi_allusers_target);
|
||||||
ft_programdata = g_file_info_get_file_type (fi_programdata);
|
ft_programdata = g_file_info_get_file_type (fi_programdata);
|
||||||
|
ft_commondata = g_file_info_get_file_type (fi_commondata);
|
||||||
|
|
||||||
g_assert (ft_allusers == G_FILE_TYPE_SYMBOLIC_LINK);
|
g_assert_cmpint (ft_allusers, ==, G_FILE_TYPE_SYMBOLIC_LINK);
|
||||||
g_assert (ft_allusers_target == G_FILE_TYPE_DIRECTORY);
|
g_assert_cmpint (ft_allusers_target, ==, G_FILE_TYPE_DIRECTORY);
|
||||||
g_assert (ft_programdata == G_FILE_TYPE_DIRECTORY);
|
g_assert_cmpint (ft_programdata, ==, G_FILE_TYPE_DIRECTORY);
|
||||||
|
g_assert_cmpint (ft_commondata, ==, G_FILE_TYPE_SYMBOLIC_LINK);
|
||||||
|
|
||||||
allusers_is_symlink = g_file_info_get_attribute_boolean (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK);
|
allusers_is_symlink = g_file_info_get_attribute_boolean (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK);
|
||||||
|
allusers_reparse_tag = g_file_info_get_attribute_uint32 (fi_allusers, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG);
|
||||||
|
commondata_is_symlink = g_file_info_get_attribute_boolean (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK);
|
||||||
|
commondata_is_mount_point = g_file_info_get_attribute_boolean (fi_commondata, G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT);
|
||||||
|
commondata_reparse_tag = g_file_info_get_attribute_uint32 (fi_commondata, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG);
|
||||||
|
|
||||||
g_assert_true (allusers_is_symlink);
|
g_assert_true (allusers_is_symlink);
|
||||||
|
g_assert_cmpuint (allusers_reparse_tag, ==, IO_REPARSE_TAG_SYMLINK);
|
||||||
|
g_assert_true (commondata_is_symlink);
|
||||||
|
g_assert_true (commondata_is_mount_point);
|
||||||
|
g_assert_cmpuint (commondata_reparse_tag, ==, IO_REPARSE_TAG_MOUNT_POINT);
|
||||||
|
|
||||||
id_allusers = g_file_info_get_attribute_string (fi_allusers, G_FILE_ATTRIBUTE_ID_FILE);
|
id_allusers = g_file_info_get_attribute_string (fi_allusers, G_FILE_ATTRIBUTE_ID_FILE);
|
||||||
id_allusers_target = g_file_info_get_attribute_string (fi_allusers_target, G_FILE_ATTRIBUTE_ID_FILE);
|
id_allusers_target = g_file_info_get_attribute_string (fi_allusers_target, G_FILE_ATTRIBUTE_ID_FILE);
|
||||||
|
id_commondata_target = g_file_info_get_attribute_string (fi_commondata_target, G_FILE_ATTRIBUTE_ID_FILE);
|
||||||
id_programdata = g_file_info_get_attribute_string (fi_programdata, G_FILE_ATTRIBUTE_ID_FILE);
|
id_programdata = g_file_info_get_attribute_string (fi_programdata, G_FILE_ATTRIBUTE_ID_FILE);
|
||||||
|
|
||||||
g_assert_cmpstr (id_allusers_target, ==, id_programdata);
|
g_assert_cmpstr (id_allusers_target, ==, id_programdata);
|
||||||
|
g_assert_cmpstr (id_commondata_target, ==, id_programdata);
|
||||||
g_assert_cmpstr (id_allusers, !=, id_programdata);
|
g_assert_cmpstr (id_allusers, !=, id_programdata);
|
||||||
|
|
||||||
allusers_target = g_file_info_get_symlink_target (fi_allusers);
|
allusers_target = g_file_info_get_symlink_target (fi_allusers);
|
||||||
|
|
||||||
g_assert_true (g_str_has_suffix (allusers_target, "ProgramData"));
|
g_assert_true (g_str_has_suffix (allusers_target, "ProgramData"));
|
||||||
|
|
||||||
|
commondata_target = g_file_info_get_symlink_target (fi_commondata);
|
||||||
|
|
||||||
|
g_assert_true (g_str_has_suffix (commondata_target, "ProgramData"));
|
||||||
|
|
||||||
g_object_unref (fi_allusers);
|
g_object_unref (fi_allusers);
|
||||||
g_object_unref (fi_allusers_target);
|
g_object_unref (fi_allusers_target);
|
||||||
|
g_object_unref (fi_commondata);
|
||||||
|
g_object_unref (fi_commondata_target);
|
||||||
g_object_unref (fi_programdata);
|
g_object_unref (fi_programdata);
|
||||||
g_object_unref (gf_allusers);
|
g_object_unref (gf_allusers);
|
||||||
|
g_object_unref (gf_commondata);
|
||||||
g_object_unref (gf_programdata);
|
g_object_unref (gf_programdata);
|
||||||
|
|
||||||
g_free (allusers);
|
g_free (allusers);
|
||||||
|
g_free (commondata);
|
||||||
g_free (users_dir);
|
g_free (users_dir);
|
||||||
g_free (programdata);
|
g_free (programdata);
|
||||||
}
|
}
|
||||||
@ -325,7 +385,7 @@ test_internal_enhanced_stdio (void)
|
|||||||
g_assert_nonnull (f);
|
g_assert_nonnull (f);
|
||||||
|
|
||||||
h = (HANDLE) _get_osfhandle (fileno (f));
|
h = (HANDLE) _get_osfhandle (fileno (f));
|
||||||
g_assert (h != INVALID_HANDLE_VALUE);
|
g_assert_cmpuint ((guintptr) h, !=, (guintptr) INVALID_HANDLE_VALUE);
|
||||||
|
|
||||||
ssb.SetSparse = TRUE;
|
ssb.SetSparse = TRUE;
|
||||||
g_assert_true (DeviceIoControl (h,
|
g_assert_true (DeviceIoControl (h,
|
||||||
@ -364,8 +424,8 @@ test_internal_enhanced_stdio (void)
|
|||||||
|
|
||||||
g_remove (ps);
|
g_remove (ps);
|
||||||
|
|
||||||
g_assert (g_file_info_has_attribute (fi_ps, G_FILE_ATTRIBUTE_STANDARD_SIZE));
|
g_assert_true (g_file_info_has_attribute (fi_ps, G_FILE_ATTRIBUTE_STANDARD_SIZE));
|
||||||
g_assert (g_file_info_has_attribute (fi_ps, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
|
g_assert_true (g_file_info_has_attribute (fi_ps, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
|
||||||
|
|
||||||
size_ps = g_file_info_get_attribute_uint64 (fi_ps, G_FILE_ATTRIBUTE_STANDARD_SIZE);
|
size_ps = g_file_info_get_attribute_uint64 (fi_ps, G_FILE_ATTRIBUTE_STANDARD_SIZE);
|
||||||
alsize_ps = g_file_info_get_attribute_uint64 (fi_ps, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE);
|
alsize_ps = g_file_info_get_attribute_uint64 (fi_ps, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE);
|
||||||
@ -404,7 +464,7 @@ test_internal_enhanced_stdio (void)
|
|||||||
g_assert_nonnull (f);
|
g_assert_nonnull (f);
|
||||||
|
|
||||||
h = (HANDLE) _get_osfhandle (fileno (f));
|
h = (HANDLE) _get_osfhandle (fileno (f));
|
||||||
g_assert (h != INVALID_HANDLE_VALUE);
|
g_assert_cmpuint ((guintptr) h, !=, (guintptr) INVALID_HANDLE_VALUE);
|
||||||
|
|
||||||
fprintf (f, "1");
|
fprintf (f, "1");
|
||||||
fflush (f);
|
fflush (f);
|
||||||
@ -443,15 +503,15 @@ test_internal_enhanced_stdio (void)
|
|||||||
G_FILE_QUERY_INFO_NONE,
|
G_FILE_QUERY_INFO_NONE,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
g_assert (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_STANDARD_SIZE));
|
g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_STANDARD_SIZE));
|
||||||
g_assert (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
|
g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
|
||||||
g_assert (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_ID_FILE));
|
g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_ID_FILE));
|
||||||
g_assert (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED));
|
g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED));
|
||||||
|
|
||||||
g_assert (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_STANDARD_SIZE));
|
g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_STANDARD_SIZE));
|
||||||
g_assert (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
|
g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
|
||||||
g_assert (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_ID_FILE));
|
g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_ID_FILE));
|
||||||
g_assert (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_TIME_MODIFIED));
|
g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_TIME_MODIFIED));
|
||||||
|
|
||||||
size_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_STANDARD_SIZE);
|
size_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_STANDARD_SIZE);
|
||||||
alsize_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE);
|
alsize_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE);
|
||||||
@ -469,7 +529,7 @@ test_internal_enhanced_stdio (void)
|
|||||||
/* st_ino from W32 stat() is useless for file identification.
|
/* st_ino from W32 stat() is useless for file identification.
|
||||||
* It will be either 0, or it will be the same for both files.
|
* It will be either 0, or it will be the same for both files.
|
||||||
*/
|
*/
|
||||||
g_assert (statbuf_p0.st_ino == statbuf_p1.st_ino);
|
g_assert_cmpint (statbuf_p0.st_ino, ==, statbuf_p1.st_ino);
|
||||||
g_assert_cmpstr (id_p0, !=, id_p1);
|
g_assert_cmpstr (id_p0, !=, id_p1);
|
||||||
|
|
||||||
time_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED);
|
time_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED);
|
||||||
@ -481,7 +541,7 @@ test_internal_enhanced_stdio (void)
|
|||||||
* and 64-bit on 64-bit Windows, usually),
|
* and 64-bit on 64-bit Windows, usually),
|
||||||
* so it *can* pass this test in some cases.
|
* so it *can* pass this test in some cases.
|
||||||
*/
|
*/
|
||||||
g_assert (time_p0 > G_GUINT64_CONSTANT (0xFFFFFFFF));
|
g_assert_cmpuint (time_p0, >, G_GUINT64_CONSTANT (0xFFFFFFFF));
|
||||||
|
|
||||||
g_object_unref (fi_p0);
|
g_object_unref (fi_p0);
|
||||||
g_object_unref (fi_p1);
|
g_object_unref (fi_p1);
|
||||||
|
77
glib/gstdio-private.c
Normal file
77
glib/gstdio-private.c
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/* gstdio-private.c - private glib functions for gstdio.c
|
||||||
|
*
|
||||||
|
* Copyright 2004 Tor Lillqvist
|
||||||
|
* Copyright 2018 Руслан Ижбулатов
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Strips "\\\\?\\" extended prefix or
|
||||||
|
* "\\??\\" NT Object Manager prefix from
|
||||||
|
* @str in-place, using memmove.
|
||||||
|
* @str_size must point to the size of @str
|
||||||
|
* in gunichar2s, including NUL-terminator
|
||||||
|
* (if @str is NUL-terminated; it doesn't have to be).
|
||||||
|
* On return @str_size will correctly reflect changes
|
||||||
|
* in @str size (if any).
|
||||||
|
* Returns TRUE if @str was modified.
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
_g_win32_strip_extended_ntobjm_prefix (gunichar2 *str,
|
||||||
|
gsize *str_size)
|
||||||
|
{
|
||||||
|
const wchar_t *extended_prefix = L"\\\\?\\";
|
||||||
|
const gsize extended_prefix_len = wcslen (extended_prefix);
|
||||||
|
const gsize extended_prefix_len_bytes = sizeof (gunichar2) * extended_prefix_len;
|
||||||
|
const gsize extended_prefix_with_drive_len_bytes = sizeof (gunichar2) * (extended_prefix_len + 2);
|
||||||
|
const wchar_t *ntobjm_prefix = L"\\??\\";
|
||||||
|
const gsize ntobjm_prefix_len = wcslen (ntobjm_prefix);
|
||||||
|
const gsize ntobjm_prefix_len_bytes = sizeof (gunichar2) * ntobjm_prefix_len;
|
||||||
|
const gsize ntobjm_prefix_with_drive_len_bytes = sizeof (gunichar2) * (ntobjm_prefix_len + 2);
|
||||||
|
gboolean do_move = FALSE;
|
||||||
|
gsize move_shift = 0;
|
||||||
|
|
||||||
|
if ((*str_size) * sizeof (gunichar2) > extended_prefix_with_drive_len_bytes &&
|
||||||
|
memcmp (str,
|
||||||
|
extended_prefix,
|
||||||
|
extended_prefix_len_bytes) == 0 &&
|
||||||
|
iswascii (str[extended_prefix_len]) &&
|
||||||
|
iswalpha (str[extended_prefix_len]) &&
|
||||||
|
str[extended_prefix_len + 1] == L':')
|
||||||
|
{
|
||||||
|
do_move = TRUE;
|
||||||
|
move_shift = extended_prefix_len;
|
||||||
|
}
|
||||||
|
else if ((*str_size) * sizeof (gunichar2) > ntobjm_prefix_with_drive_len_bytes &&
|
||||||
|
memcmp (str,
|
||||||
|
ntobjm_prefix,
|
||||||
|
ntobjm_prefix_len_bytes) == 0 &&
|
||||||
|
iswascii (str[ntobjm_prefix_len]) &&
|
||||||
|
iswalpha (str[ntobjm_prefix_len]) &&
|
||||||
|
str[ntobjm_prefix_len + 1] == L':')
|
||||||
|
{
|
||||||
|
do_move = TRUE;
|
||||||
|
move_shift = ntobjm_prefix_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (do_move)
|
||||||
|
{
|
||||||
|
*str_size -= move_shift;
|
||||||
|
memmove (str,
|
||||||
|
str + move_shift,
|
||||||
|
(*str_size) * sizeof (gunichar2));
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_move;
|
||||||
|
}
|
@ -121,6 +121,8 @@ w32_error_to_errno (DWORD error_code)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "gstdio-private.c"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_g_win32_stat_utf16_no_trailing_slashes (const gunichar2 *filename,
|
_g_win32_stat_utf16_no_trailing_slashes (const gunichar2 *filename,
|
||||||
int fd,
|
int fd,
|
||||||
@ -259,15 +261,11 @@ _g_win32_stat_utf16_no_trailing_slashes (const gunichar2 *filename,
|
|||||||
|
|
||||||
if (new_len > 0)
|
if (new_len > 0)
|
||||||
{
|
{
|
||||||
const wchar_t *extended_prefix = L"\\\\?\\";
|
|
||||||
const gsize extended_prefix_len = wcslen (extended_prefix);
|
|
||||||
const gsize extended_prefix_len_bytes = sizeof (wchar_t) * extended_prefix_len;
|
|
||||||
|
|
||||||
/* Pretend that new_len doesn't count the terminating NUL char,
|
/* Pretend that new_len doesn't count the terminating NUL char,
|
||||||
* and ask for a bit more space than is needed.
|
* and ask for a bit more space than is needed, and allocate even more.
|
||||||
*/
|
*/
|
||||||
filename_target_len = new_len + 5;
|
filename_target_len = new_len + 3;
|
||||||
filename_target = g_malloc (filename_target_len * sizeof (wchar_t));
|
filename_target = g_malloc ((filename_target_len + 1) * sizeof (wchar_t));
|
||||||
|
|
||||||
new_len = GetFinalPathNameByHandleW (file_handle,
|
new_len = GetFinalPathNameByHandleW (file_handle,
|
||||||
filename_target,
|
filename_target,
|
||||||
@ -284,17 +282,32 @@ _g_win32_stat_utf16_no_trailing_slashes (const gunichar2 *filename,
|
|||||||
error_code = ERROR_BUFFER_OVERFLOW;
|
error_code = ERROR_BUFFER_OVERFLOW;
|
||||||
g_clear_pointer (&filename_target, g_free);
|
g_clear_pointer (&filename_target, g_free);
|
||||||
}
|
}
|
||||||
/* GetFinalPathNameByHandle() is documented to return extended paths,
|
else if (new_len == 0)
|
||||||
* strip the extended prefix.
|
|
||||||
*/
|
|
||||||
else if (new_len > extended_prefix_len &&
|
|
||||||
memcmp (filename_target, extended_prefix, extended_prefix_len_bytes) == 0)
|
|
||||||
{
|
{
|
||||||
new_len -= extended_prefix_len;
|
g_clear_pointer (&filename_target, g_free);
|
||||||
memmove (filename_target,
|
|
||||||
filename_target + extended_prefix_len,
|
|
||||||
(new_len + 1) * sizeof (wchar_t));
|
|
||||||
}
|
}
|
||||||
|
/* GetFinalPathNameByHandle() is documented to return extended paths,
|
||||||
|
* strip the extended prefix, if it is followed by a drive letter
|
||||||
|
* and a colon. Otherwise keep it (the path could be
|
||||||
|
* \\\\?\\Volume{GUID}\\ - it's only usable in extended form).
|
||||||
|
*/
|
||||||
|
else if (new_len > 0)
|
||||||
|
{
|
||||||
|
gsize len = new_len;
|
||||||
|
|
||||||
|
/* Account for NUL-terminator maybe not being counted.
|
||||||
|
* This is why we overallocated earlier.
|
||||||
|
*/
|
||||||
|
if (filename_target[len] != L'\0')
|
||||||
|
{
|
||||||
|
len++;
|
||||||
|
filename_target[len] = L'\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
_g_win32_strip_extended_ntobjm_prefix (filename_target, &len);
|
||||||
|
new_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_len == 0)
|
if (new_len == 0)
|
||||||
@ -453,8 +466,9 @@ _g_win32_readlink_utf16_raw (const gunichar2 *filename,
|
|||||||
* point and use DeviceIoControl() on it.
|
* point and use DeviceIoControl() on it.
|
||||||
*/
|
*/
|
||||||
h = CreateFileW (filename,
|
h = CreateFileW (filename,
|
||||||
FILE_READ_ATTRIBUTES | SYNCHRONIZE | GENERIC_READ,
|
FILE_READ_EA,
|
||||||
FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
|
||||||
|
NULL, OPEN_EXISTING,
|
||||||
FILE_ATTRIBUTE_NORMAL
|
FILE_ATTRIBUTE_NORMAL
|
||||||
| FILE_FLAG_OPEN_REPARSE_POINT
|
| FILE_FLAG_OPEN_REPARSE_POINT
|
||||||
| (attributes & FILE_ATTRIBUTE_DIRECTORY ? FILE_FLAG_BACKUP_SEMANTICS : 0),
|
| (attributes & FILE_ATTRIBUTE_DIRECTORY ? FILE_FLAG_BACKUP_SEMANTICS : 0),
|
||||||
@ -513,10 +527,8 @@ _g_win32_readlink_utf16 (const gunichar2 *filename,
|
|||||||
gunichar2 *buf,
|
gunichar2 *buf,
|
||||||
gsize buf_size)
|
gsize buf_size)
|
||||||
{
|
{
|
||||||
const wchar_t *ntobjm_prefix = L"\\??\\";
|
int result = _g_win32_readlink_utf16_raw (filename, buf, buf_size);
|
||||||
const gsize ntobjm_prefix_len_unichar2 = wcslen (ntobjm_prefix);
|
gsize string_size;
|
||||||
const gsize ntobjm_prefix_len_bytes = sizeof (gunichar2) * ntobjm_prefix_len_unichar2;
|
|
||||||
int result = _g_win32_readlink_utf16_raw (filename, buf, buf_size);
|
|
||||||
|
|
||||||
if (result <= 0)
|
if (result <= 0)
|
||||||
return result;
|
return result;
|
||||||
@ -532,16 +544,16 @@ _g_win32_readlink_utf16 (const gunichar2 *filename,
|
|||||||
/* DeviceIoControl () tends to return filenames as NT Object Manager
|
/* DeviceIoControl () tends to return filenames as NT Object Manager
|
||||||
* names , i.e. "\\??\\C:\\foo\\bar".
|
* names , i.e. "\\??\\C:\\foo\\bar".
|
||||||
* Remove the leading 4-byte \??\ prefix, as glib (as well as many W32 API
|
* Remove the leading 4-byte \??\ prefix, as glib (as well as many W32 API
|
||||||
* functions) is unprepared to deal with it.
|
* functions) is unprepared to deal with it. Unless it has no 'x:' drive
|
||||||
|
* letter part after the prefix, in which case we leave everything
|
||||||
|
* as-is, because the path could be "\??\Volume{GUID}" - stripping
|
||||||
|
* the prefix will allow it to be confused with relative links
|
||||||
|
* targeting "Volume{GUID}".
|
||||||
*/
|
*/
|
||||||
if (result > ntobjm_prefix_len_bytes &&
|
string_size = result / sizeof (gunichar2);
|
||||||
memcmp (buf, ntobjm_prefix, ntobjm_prefix_len_bytes) == 0)
|
_g_win32_strip_extended_ntobjm_prefix (buf, &string_size);
|
||||||
{
|
|
||||||
result -= ntobjm_prefix_len_bytes;
|
|
||||||
memmove (buf, buf + ntobjm_prefix_len_unichar2, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return string_size * sizeof (gunichar2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
|
@ -1009,6 +1009,139 @@ test_fopen_modes (void)
|
|||||||
g_free (path);
|
g_free (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
#include "../gstdio-private.c"
|
||||||
|
|
||||||
|
static int
|
||||||
|
g_wcscmp0 (const gunichar2 *str1,
|
||||||
|
const gunichar2 *str2)
|
||||||
|
{
|
||||||
|
if (!str1)
|
||||||
|
return -(str1 != str2);
|
||||||
|
if (!str2)
|
||||||
|
return str1 != str2;
|
||||||
|
return wcscmp (str1, str2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define g_assert_cmpwcs(s1, cmp, s2, s1u8, s2u8) \
|
||||||
|
G_STMT_START { \
|
||||||
|
const gunichar2 *__s1 = (s1), *__s2 = (s2); \
|
||||||
|
if (g_wcscmp0 (__s1, __s2) cmp 0) ; else \
|
||||||
|
g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
|
||||||
|
#s1u8 " " #cmp " " #s2u8, s1u8, #cmp, s2u8); \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_win32_pathstrip (void)
|
||||||
|
{
|
||||||
|
gunichar2 *buf;
|
||||||
|
gsize i;
|
||||||
|
#define IDENTITY_TEST(x) { x, x, FALSE }
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
gunichar2 *in;
|
||||||
|
gunichar2 *out;
|
||||||
|
gboolean result;
|
||||||
|
} testcases[] = {
|
||||||
|
IDENTITY_TEST (L"\\\\?\\V"),
|
||||||
|
IDENTITY_TEST (L"\\\\?\\Vo"),
|
||||||
|
IDENTITY_TEST (L"\\\\?\\Volume{0700f3d3-6d24-11e3-8b2f-806e6f6e6963}\\"),
|
||||||
|
IDENTITY_TEST (L"\\??\\V"),
|
||||||
|
IDENTITY_TEST (L"\\??\\Vo"),
|
||||||
|
IDENTITY_TEST (L"\\??\\Volume{0700f3d3-6d24-11e3-8b2f-806e6f6e6963}\\"),
|
||||||
|
IDENTITY_TEST (L"\\\\?\\\x0441:\\"),
|
||||||
|
IDENTITY_TEST (L"\\??\\\x0441:\\"),
|
||||||
|
IDENTITY_TEST (L"a:\\"),
|
||||||
|
IDENTITY_TEST (L"a:\\b\\c"),
|
||||||
|
IDENTITY_TEST (L"x"),
|
||||||
|
#undef IDENTITY_TEST
|
||||||
|
{
|
||||||
|
L"\\\\?\\c:\\",
|
||||||
|
L"c:\\",
|
||||||
|
TRUE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
L"\\\\?\\C:\\",
|
||||||
|
L"C:\\",
|
||||||
|
TRUE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
L"\\\\?\\c:\\",
|
||||||
|
L"c:\\",
|
||||||
|
TRUE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
L"\\\\?\\C:\\",
|
||||||
|
L"C:\\",
|
||||||
|
TRUE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
L"\\\\?\\C:\\",
|
||||||
|
L"C:\\",
|
||||||
|
TRUE,
|
||||||
|
},
|
||||||
|
{ 0, }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; testcases[i].in; i++)
|
||||||
|
{
|
||||||
|
gsize str_len = wcslen (testcases[i].in) + 1;
|
||||||
|
gchar *in_u8 = g_utf16_to_utf8 (testcases[i].in, -1, NULL, NULL, NULL);
|
||||||
|
gchar *out_u8 = g_utf16_to_utf8 (testcases[i].out, -1, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
g_assert_nonnull (in_u8);
|
||||||
|
g_assert_nonnull (out_u8);
|
||||||
|
|
||||||
|
buf = g_new0 (gunichar2, str_len);
|
||||||
|
memcpy (buf, testcases[i].in, str_len * sizeof (gunichar2));
|
||||||
|
_g_win32_strip_extended_ntobjm_prefix (buf, &str_len);
|
||||||
|
g_assert_cmpwcs (buf, ==, testcases[i].out, in_u8, out_u8);
|
||||||
|
g_free (buf);
|
||||||
|
g_free (in_u8);
|
||||||
|
g_free (out_u8);
|
||||||
|
}
|
||||||
|
/* Check for correct behaviour on non-NUL-terminated strings */
|
||||||
|
for (i = 0; testcases[i].in; i++)
|
||||||
|
{
|
||||||
|
gsize str_len = wcslen (testcases[i].in) + 1;
|
||||||
|
wchar_t old_endchar;
|
||||||
|
gchar *in_u8 = g_utf16_to_utf8 (testcases[i].in, -1, NULL, NULL, NULL);
|
||||||
|
gchar *out_u8 = g_utf16_to_utf8 (testcases[i].out, -1, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
g_assert_nonnull (in_u8);
|
||||||
|
g_assert_nonnull (out_u8);
|
||||||
|
|
||||||
|
buf = g_new0 (gunichar2, str_len);
|
||||||
|
memcpy (buf, testcases[i].in, (str_len) * sizeof (gunichar2));
|
||||||
|
|
||||||
|
old_endchar = buf[wcslen (testcases[i].out)];
|
||||||
|
str_len -= 1;
|
||||||
|
|
||||||
|
if (testcases[i].result)
|
||||||
|
{
|
||||||
|
/* Given "\\\\?\\C:\\" (len 7, unterminated),
|
||||||
|
* we should get "C:\\" (len 3, unterminated).
|
||||||
|
* Put a character different from "\\" (4-th character of the buffer)
|
||||||
|
* at the end of the unterminated source buffer, into a position
|
||||||
|
* where NUL-terminator would normally be. Then later test that 4-th character
|
||||||
|
* in the buffer is still the old "\\".
|
||||||
|
* After that terminate the string and use normal g_wcscmp0().
|
||||||
|
*/
|
||||||
|
buf[str_len] = old_endchar - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
_g_win32_strip_extended_ntobjm_prefix (buf, &str_len);
|
||||||
|
g_assert_cmpuint (old_endchar, ==, buf[wcslen (testcases[i].out)]);
|
||||||
|
buf[str_len] = L'\0';
|
||||||
|
g_assert_cmpwcs (buf, ==, testcases[i].out, in_u8, out_u8);
|
||||||
|
g_free (buf);
|
||||||
|
g_free (in_u8);
|
||||||
|
g_free (out_u8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
@ -1018,6 +1151,9 @@ main (int argc,
|
|||||||
|
|
||||||
g_test_bug_base ("https://gitlab.gnome.org/GNOME/glib/merge_requests/");
|
g_test_bug_base ("https://gitlab.gnome.org/GNOME/glib/merge_requests/");
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
g_test_add_func ("/fileutils/stdio-win32-pathstrip", test_win32_pathstrip);
|
||||||
|
#endif
|
||||||
g_test_add_func ("/fileutils/build-path", test_build_path);
|
g_test_add_func ("/fileutils/build-path", test_build_path);
|
||||||
g_test_add_func ("/fileutils/build-pathv", test_build_pathv);
|
g_test_add_func ("/fileutils/build-pathv", test_build_pathv);
|
||||||
g_test_add_func ("/fileutils/build-filename", test_build_filename);
|
g_test_add_func ("/fileutils/build-filename", test_build_filename);
|
||||||
|
Loading…
Reference in New Issue
Block a user