\\?\ и ..
От: BigBoss  
Дата: 23.08.15 22:04
Оценка:
И снова здравствуйте!

MSDN утверждает

Because it turns off automatic expansion of the path string, the "\\?\" prefix also allows the use of ".." and "." in the path names, which can be useful if you are attempting to perform operations on a file with these otherwise reserved relative path specifiers as part of the fully qualified path.


Однако CreateFile() возвращакт оибку 123 (The filename, directory name, or volume label syntax is incorrect.) на попытку открыть "\\?\C:\Windows\Temp\..\win.ini". Без "\\?\" файл открывается.
Так можно использовать относительные пути с "\\?\" или нет???
Re: \\?\ и ..
От: VTT http://vtt.to
Дата: 24.08.15 07:11
Оценка:
Здравствуйте, BigBoss, Вы писали:

А вы вызываете юникод версию этой функции?
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re: \\?\ и ..
От: CaptainFlint http://flint-inc.ru/
Дата: 24.08.15 08:49
Оценка: +3 -1
Здравствуйте, BigBoss, Вы писали:

BB>И снова здравствуйте!


BB>MSDN утверждает

BB>

BB>Because it turns off automatic expansion of the path string, the "\\?\" prefix also allows the use of ".." and "." in the path names, which can be useful if you are attempting to perform operations on a file with these otherwise reserved relative path specifiers as part of the fully qualified path.


BB>Однако CreateFile() возвращакт оибку 123 (The filename, directory name, or volume label syntax is incorrect.) на попытку открыть "\\?\C:\Windows\Temp\..\win.ini". Без "\\?\" файл открывается.

BB>Так можно использовать относительные пути с "\\?\" или нет???

Как я понял, речь тут о другом. Эти имена (. и ..) являются зарезервированными для обозначения текущего/родительского каталога, но в самой файловой системе могло получиться так, что есть файл или каталог с таким именем. Тогда обычным способом к нему не обратишься, а с префиксом \\?\ спец-трактовка отключается, и такие файлы-каталоги можно будет открывать.
Файл "\\?\C:\Windows\Temp\..\win.ini" не открывается по той причине, что "физического" каталога C:\Windows\Temp\..\ не существует, а трактовка ".." как перехода в родительский каталог отключена префиксом \\?\.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[2]: \\?\ и ..
От: ononim  
Дата: 24.08.15 09:43
Оценка:
BB>>Однако CreateFile() возвращакт оибку 123 (The filename, directory name, or volume label syntax is incorrect.) на попытку открыть "\\?\C:\Windows\Temp\..\win.ini". Без "\\?\" файл открывается.
BB>>Так можно использовать относительные пути с "\\?\" или нет???
CF>Как я понял, речь тут о другом. Эти имена (. и ..) являются зарезервированными для обозначения текущего/родительского каталога, но в самой файловой системе могло получиться так, что есть файл или каталог с таким именем. Тогда обычным способом к нему не обратишься, а с префиксом \\?\ спец-трактовка отключается, и такие файлы-каталоги можно будет открывать.
CF>Файл "\\?\C:\Windows\Temp\..\win.ini" не открывается по той причине, что "физического" каталога C:\Windows\Temp\..\ не существует, а трактовка ".." как перехода в родительский каталог отключена префиксом \\?\.
Только есть подозрение что это сработает (создать такой каталог) выйдет только на особо древних виндах. Используя native API я создавал корявые файлы с прямым слэшем, но еще вроде в каком то патче под ХР это "починили".
Как много веселых ребят, и все делают велосипед...
Re: \\?\ и ..
От: verizon  
Дата: 24.08.15 10:21
Оценка:
всё дело в функции RtlDosPathNameToNtPathName_U — она вызывается для конвертирования win32 пути в native. но работает она скажем так не всегда предсказуема при "сложных" путях. более того, есть случаи когда один и тот же путь по разному конвертится в xp, 7 и 8 — во всвех виндах по разному. вот простой тест и вывод из него:

void TestConvert(PCWSTR DosPathName)
{
    UNICODE_STRING us;
    if (RtlDosPathNameToNtPathName_U(DosPathName, &us, 0, 0))
    {
        DbgPrint("%S -> %wZ\n", DosPathName, &us);
        RtlFreeUnicodeString(&us);
    }
}
    TestConvert(L"C:\\..\\Windows\\win.ini");
    TestConvert(L"C:\\..\\..\\xx");
    TestConvert(L"C:\\..\\xx");
    TestConvert(L"\\\\?\\C:\\..\\Windows\\win.ini");
    TestConvert(L"\\\\.\\C:\\..\\Windows\\win.ini");
    TestConvert(L"C:\\Windows\\win.ini");
    TestConvert(L"\\\\?\\C:\\Windows\\win.ini");
    TestConvert(L"\\\\.\\C:\\Windows\\win.ini");
---------------------------------------------------------------------
C:\..\Windows\win.ini -> \??\C:\Windows\win.ini
C:\..\..\xx -> \??\C:\xx
C:\..\xx -> \??\C:\xx
\\?\C:\..\Windows\win.ini -> \??\C:\..\Windows\win.ini
\\.\C:\..\Windows\win.ini -> \??\Windows\win.ini
C:\Windows\win.ini -> \??\C:\Windows\win.ini
\\?\C:\Windows\win.ini -> \??\C:\Windows\win.ini
\\.\C:\Windows\win.ini -> \??\C:\Windows\win.ini
Re[2]: \\?\ и ..
От: verizon  
Дата: 24.08.15 10:56
Оценка: -1
всё это мимо кассы. файловая система здесь вообще не причём. всё дело в конверте из win32 пути в настоящий (native) путь. в функции RtlDosPathNameToNtPathName_U
Re[3]: \\?\ и ..
От: ononim  
Дата: 24.08.15 11:09
Оценка:
V>всё это мимо кассы. файловая система здесь вообще не причём. всё дело в конверте из win32 пути в настоящий (native) путь. в функции RtlDosPathNameToNtPathName_U
В случае передачи \\?\ сия конверсия представляет собой замену второго слэша на знак вопроса, то есть отключается win32 "предпарсинг", так что все правильно CaptainFlint сказал.
Как много веселых ребят, и все делают велосипед...
Отредактировано 24.08.2015 11:12 ononim . Предыдущая версия .
Re[4]: \\?\ и ..
От: verizon  
Дата: 24.08.15 11:33
Оценка:
Здравствуйте, ononim, Вы писали:

V>>всё это мимо кассы. файловая система здесь вообще не причём. всё дело в конверте из win32 пути в настоящий (native) путь. в функции RtlDosPathNameToNtPathName_U

O>В случае передачи \\?\ сия конверсия представляет собой замену второго слэша на знак вопроса, то есть отключается win32 "предпарсинг"

не всегда. кроме того есть ещё вариант \\.\ — он в большинстве обычных случаев работает также как \\?\ но иногда по другому. кроме того протестируйте пути вида *\\-.\\* и с \\?\ и с \\.\ и без префиксов — на xp,7, 8 — там вообще сказка. а файловая система здесь не причём — она всегда работает с NT путями. все же описанные "приколы" связаны с конвертацией win32 пути в NT
Re[5]: \\?\ и ..
От: verizon  
Дата: 24.08.15 11:56
Оценка:

не всегда.

хотя нет, здесь я не прав, похоже с префиксом \\?\ — всегда происходит замена на \??\ без парсинга. но главную суть это не меняет — дело не в файловой системе а в конвертации win32 -> NT (если я правильно понял суть вопроса)
Re[2]: \\?\ и ..
От: BigBoss  
Дата: 24.08.15 23:55
Оценка:
Здравствуйте, CaptainFlint, Вы писали:

CF>Как я понял, речь тут о другом. Эти имена (. и ..) являются зарезервированными для обозначения текущего/родительского каталога, но в самой файловой системе могло получиться так, что есть файл или каталог с таким именем. Тогда обычным способом к нему не обратишься, а с префиксом \\?\ спец-трактовка отключается, и такие файлы-каталоги можно будет открывать.

CF>Файл "\\?\C:\Windows\Temp\..\win.ini" не открывается по той причине, что "физического" каталога C:\Windows\Temp\..\ не существует, а трактовка ".." как перехода в родительский каталог отключена префиксом \\?\.

Спасибо, всё верно, это я протормозил. После создания покаталога ".." всё заработало как описано в MSDN.
Re[5]: \\?\ и ..
От: BigBoss  
Дата: 25.08.15 00:23
Оценка:
Здравствуйте, verizon, Вы писали:

V>не всегда. кроме того есть ещё вариант \\.\ — он в большинстве обычных случаев работает также как \\?\ но иногда по другому. кроме того протестируйте пути вида *\\-.\\* и с \\?\ и с \\.\ и без префиксов — на xp,7, 8 — там вообще сказка. а файловая система здесь не причём — она всегда работает с NT путями. все же описанные "приколы" связаны с конвертацией win32 пути в NT


\\?\ и \\.\ -- это две документированые разницы. Первая есть обращение к файловой системе, второе -- к пространству имён win32. Случайно обе они понимают что-то вроде С:\хх или COM2: , но по-разному. Из Вашего примера чуть ниже видно, что файловая система не нормализирует пути, а \\.\ это делает, так же как и для "DOS'овских" путей (вызовом чего-нибудь вроде PathCanonicalize())
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.