summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/ntapi/nt_stat.h1
-rw-r--r--src/fs/ntapi_tt_stat.c59
2 files changed, 45 insertions, 15 deletions
diff --git a/include/ntapi/nt_stat.h b/include/ntapi/nt_stat.h
index 17cb080..94890b5 100644
--- a/include/ntapi/nt_stat.h
+++ b/include/ntapi/nt_stat.h
@@ -9,6 +9,7 @@
#define NT_STAT_DEFAULT (0x00000000)
#define NT_STAT_COMMON (0x00000001)
#define NT_STAT_DEV_NAME_COPY (0x00000002)
+#define NT_STAT_MUP_DEVICE (0x20000000)
#define NT_STAT_NEW_HANDLE (0x80000000)
typedef struct _nt_stat {
diff --git a/src/fs/ntapi_tt_stat.c b/src/fs/ntapi_tt_stat.c
index fbcecca..9ad9975 100644
--- a/src/fs/ntapi_tt_stat.c
+++ b/src/fs/ntapi_tt_stat.c
@@ -26,6 +26,9 @@ int32_t __stdcall __ntapi_tt_stat(
nt_iosb iosb;
nt_unicode_string * sdev;
nt_fai * fai;
+ wchar16_t * wch;
+ wchar16_t * wch_mark;
+ uint32_t hash;
/* validation */
if (!hfile && !path)
@@ -93,25 +96,51 @@ int32_t __stdcall __ntapi_tt_stat(
if (status != NT_STATUS_SUCCESS)
return status;
- /* system-unique device name (simpler than statfs) */
- iosb.info = 0;
- status = __ntapi->zw_query_object(
- hfile,
- NT_OBJECT_NAME_INFORMATION,
- buffer,
- buffer_size,
- (uint32_t *)&iosb.info);
-
- if (status != NT_STATUS_SUCCESS)
+ /* system-unique device name */
+ if ((status = __ntapi->zw_query_object(
+ hfile,
+ NT_OBJECT_NAME_INFORMATION,
+ buffer,
+ buffer_size,
+ (uint32_t *)&iosb.info)))
return status;
sdev = (nt_unicode_string *)buffer;
- stat->dev_name_strlen = sdev->strlen - (uint16_t)stat->file_name_length;
+ wch = sdev->buffer;
+
+ if (sdev->strlen < __DEVICE_PATH_PREFIX_LEN)
+ return NT_STATUS_INVALID_HANDLE;
+
+ if ((wch[0] != '\\')
+ || (wch[1] != 'D')
+ || (wch[2] != 'e')
+ || (wch[3] != 'v')
+ || (wch[4] != 'i')
+ || (wch[5] != 'c')
+ || (wch[6] != 'e')
+ || (wch[7] != '\\'))
+ return NT_STATUS_INVALID_HANDLE;
+
+ if ((sdev->strlen >= __DEVICE_MUP_PREFIX_LEN)
+ && (wch[8]=='M')
+ && (wch[9]=='u')
+ && (wch[10]=='p')
+ && (wch[11]=='\\')) {
+ stat->flags_out |= NT_STAT_MUP_DEVICE;
+ wch_mark = &wch[12];
+ hash = __DEVICE_MUP_PREFIX_HASH;
+ } else {
+ wch_mark = &wch[8];
+ hash = __DEVICE_PATH_PREFIX_HASH;
+ }
+
+ for (wch=wch_mark; *wch!='\\'; wch++)
+ (void)0;
- stat->dev_name_hash = __ntapi->tt_buffer_crc32(
- 0,
- sdev->buffer,
- stat->dev_name_strlen);
+ stat->dev_name_strlen = (uint16_t)((wch - sdev->buffer) * sizeof(uint16_t));
+ stat->dev_name_hash = __ntapi->tt_buffer_crc32(
+ hash,wch_mark,
+ sizeof(wchar16_t)*(wch-wch_mark));
if (flags & NT_STAT_DEV_NAME_COPY) {
if (stat->dev_name_maxlen < sdev->strlen)