View Issue Details

IDProjectCategoryView StatusLast Update
0000699Far ManagerFile Systempublic2009-04-05 12:11
Reportermda Assigned ToDrKnS  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Platformx86OSWindowsOS VersionXP SP3
Fixed in Version2.0 
Summary0000699: Вызов функций FindFirstFileW и GetShortPathNameW с некорректными параметрами
DescriptionВ MSDN написано, что при вызове юникодных версий этих функций необходимо к имени файла(маски файла) добавлять префикс "\\?\". Что этот патч и делает.
Additional InformationСказывалось на нереальных сроках обновления списка сетевых шар, что очень напрягало при хождении по сети.
TagsNo tags attached.
Build796

Activities

2009-01-13 12:47

 

find_first_file.patch (1,103 bytes)   
Index: farwinapi.cpp
===================================================================
--- farwinapi.cpp	(revision 2470)
+++ farwinapi.cpp	(working copy)
@@ -358,8 +358,11 @@
 {
     WIN32_FIND_DATAW fdata;
 
-    HANDLE hResult = FindFirstFileW (lpwszFileName, &fdata);
+	  string strCopy = "\\\\?\\";
+           strCopy += lpwszFileName;
 
+    HANDLE hResult = FindFirstFileW (strCopy, &fdata);
+
 		if(hResult==INVALID_HANDLE_VALUE && ScanSymLink)
 		{
 			string strRealName;
Index: cvtname.cpp
===================================================================
--- cvtname.cpp	(revision 2470)
+++ cvtname.cpp	(working copy)
@@ -224,7 +224,8 @@
 
 void ConvertNameToShort(const wchar_t *Src, string &strDest)
 {
-	string strCopy = Src;
+	string strCopy = "\\\\?\\";
+         strCopy += Src;
 
 	int nSize = GetShortPathNameW (strCopy, NULL, 0);
 
@@ -233,6 +234,7 @@
 		wchar_t *lpwszDest = strDest.GetBuffer (nSize);
 
 		GetShortPathNameW (strCopy, lpwszDest, nSize);
+    memmove( lpwszDest, lpwszDest+4, nSize-4 );
 
 		strDest.ReleaseBuffer ();
 	}
find_first_file.patch (1,103 bytes)   

zg

2009-01-13 12:59

developer   bugnote:0002311

а можно цитату из msdn, где написано, что необходимо?

вообще идея конечно хорошая, но патч не доделан.

mda

2009-01-13 13:21

reporter   bugnote:0002312

у меня msdn, который шёл с 2005 студией. статья про FindFirstFile. ссылка на статью ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.WIN32COM.v10.en/fileio/fs/findfirstfile.htm

цитата:
lpFileName
[in] A pointer to a null-terminated string that specifies a valid directory or path, and file name that can contain wildcard characters (* and ?).
...
In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. For more information, see Naming a File.
...

Следуя ссылке на "Naming a File" в разделе "Maximum Path Length" читаем про префиксы "\\?\" и "\\?\UNC\".

Почему с этими префиксами работает быстрее не знаю, но это факт. Признаю, что с 'необходимо' я погорячился ;)

поясни про "не доделан"

2009-01-13 13:32

 

find_first_file2.patch (1,362 bytes)   
Index: farwinapi.cpp
===================================================================
--- farwinapi.cpp	(revision 2470)
+++ farwinapi.cpp	(working copy)
@@ -358,13 +358,18 @@
 {
     WIN32_FIND_DATAW fdata;
 
-    HANDLE hResult = FindFirstFileW (lpwszFileName, &fdata);
+    string strCopy = "\\\\?\\";
+          strCopy += lpwszFileName;
 
+    HANDLE hResult = FindFirstFileW (strCopy, &fdata);
+
 		if(hResult==INVALID_HANDLE_VALUE && ScanSymLink)
 		{
 			string strRealName;
 			ConvertNameToReal(lpwszFileName,strRealName);
-			hResult=FindFirstFileW(strRealName,&fdata);
+	    strCopy = "\\\\?\\";
+     strCopy += strRealName;
+			hResult=FindFirstFileW(strCopy,&fdata);
 		}
 
     if ( hResult != INVALID_HANDLE_VALUE )
Index: cvtname.cpp
===================================================================
--- cvtname.cpp	(revision 2470)
+++ cvtname.cpp	(working copy)
@@ -224,7 +224,8 @@
 
 void ConvertNameToShort(const wchar_t *Src, string &strDest)
 {
-	string strCopy = Src;
+	string strCopy = "\\\\?\\";
+         strCopy += Src;
 
 	int nSize = GetShortPathNameW (strCopy, NULL, 0);
 
@@ -233,6 +234,7 @@
 		wchar_t *lpwszDest = strDest.GetBuffer (nSize);
 
 		GetShortPathNameW (strCopy, lpwszDest, nSize);
+    memmove( lpwszDest, lpwszDest+4, nSize-4 );
 
 		strDest.ReleaseBuffer ();
 	}
find_first_file2.patch (1,362 bytes)   

mda

2009-01-13 13:34

reporter   bugnote:0002313

вроде доделал в следующей версии патча

zg

2009-01-13 13:51

developer   bugnote:0002314

почему быстрее, очевидно из процитированого msdn. из него же должно быть очевидно, что при использовании \\?\ появляется возможность использвать более длинные пути. но править надо все функции в которые передаётся имя файла. особенно [Get|Set]CurrentDirectory.

alexmitin

2009-01-14 04:05

reporter   bugnote:0002315

Длина пути в GetCurrentDirectory и SetCurrentDirectory ограничена MAX_PATH символов.

http://msdn.microsoft.com/en-us/library/aa365530(VS.85).aspx

От этих функций нужно вообще избавляться в коде FAR.

samlyukov

2009-02-11 13:19

reporter   bugnote:0002415

и это исправили...

alexmitin

2009-02-16 06:43

reporter   bugnote:0002459

> и это исправили...

И где же исправили?

[offtop.on]
Файл: farwinapi.cpp
Функция: apiSetCurrentDirectory

Эта функция всё еще использует SetCurrentDirectory. Для функции SetCurrentDirectory добавление "\\?\" или "\\?\UNC\" просто не работает. Ограничение в MAX_PATH остается - проверьте сами. Тоже самое и для GetCurrentDirectory. Т.е. само использование SetCurrentDirectory и GetCurrentDirectory должно быть табу.

Реализация функций apiSetCurrentDirectory и apiGetCurrentDirectory должна быть немного сложнее. Придётся вести списки текущей директории для каждого подмонтированного диска (C:\test, D:\mydir и т.п.) и замапленной шары (\\myserver\share\dir, и т.п.) , а также подключенных, но не подмонтированных томов (\\?\Volume{06944d33-266d-11d9-b45d-0011222469342}\dir1\dir2 и т.п.). При добавлении или удалении томов, шар - добавлять/удалять элементы из списка.

Также нужно учитывать, что apiSetCurrentDirectory может принять относительный путь - вот для этого и нужны списки.

Вот выдержка из "Changing the Current Directory" что делает SetCurrentDirectory:
http://msdn.microsoft.com/en-us/library/aa363806(VS.85).aspx

Note Although each process can have only one current directory, if the application switches volumes using the SetCurrentDirectory function, the system remembers the last current path for each volume (drive letter). This behavior will manifest itself only when specifying a drive letter without a fully qualified path when changing the current directory point of reference to a different volume. This applies to either Get or Set operations.


Предлагаю перенести обсуждение реализации apiSetCurrentDirectory и apiGetCurrentDirectory в 0000423.
[offtop.off]

samlyukov

2009-02-16 07:22

reporter   bugnote:0002460

топик как называется? при чем тут CurrentDirectory?
закрыть нужно.

DrKnS

2009-02-16 16:28

administrator   bugnote:0002463

> Для функции SetCurrentDirectory добавление "\\?\" или "\\?\UNC\" просто не работает. Ограничение в MAX_PATH остается - проверьте сами.

1. Вы таки думаете, что все вокруг слепые и не заметили, да?
2. Если очень сильно захотеть - работает.

> Т.е. само использование SetCurrentDirectory и GetCurrentDirectory должно быть табу.

Я поясню.
Оторвать <G|S>etCurrentDirectory от фара - ОЧЕНЬ просто, проверено. Работать будет всё - и длинные имена, и относительные пути, и запускатель.
Всё, кроме одного - плагинов, которые УЖЕ используют CurrentDirectory. А плагинов таких - туева хуча, они УЖЕ написаны, и говорить им "табу" - поздно.

alexmitin

2009-02-17 08:53

reporter   bugnote:0002471

Предлагаю перенести обсуждение в форум:
http://forum.farmanager.com/viewtopic.php?f=3&t=3819

alexy

2009-04-05 12:11

administrator   bugnote:0002888

Этот закрываю ибо сабж исправлен. А о currentdirectory и так уже хватает тикетов, например 423.

Issue History

Date Modified Username Field Change
2009-01-13 12:47 mda New Issue
2009-01-13 12:47 mda File Added: find_first_file.patch
2009-01-13 12:59 zg Note Added: 0002311
2009-01-13 13:21 mda Note Added: 0002312
2009-01-13 13:32 mda File Added: find_first_file2.patch
2009-01-13 13:34 mda Note Added: 0002313
2009-01-13 13:51 zg Note Added: 0002314
2009-01-13 13:55 alexy Status new => assigned
2009-01-13 13:55 alexy Assigned To => zg
2009-01-14 04:05 alexmitin Note Added: 0002315
2009-02-11 13:19 samlyukov Note Added: 0002415
2009-02-16 06:43 alexmitin Note Added: 0002459
2009-02-16 07:22 samlyukov Note Added: 0002460
2009-02-16 16:28 DrKnS Note Added: 0002463
2009-02-17 08:53 alexmitin Note Added: 0002471
2009-03-27 22:12 alexy Assigned To zg => DrKnS
2009-04-05 12:11 alexy Build => 796
2009-04-05 12:11 alexy Note Added: 0002888
2009-04-05 12:11 alexy Status assigned => closed
2009-04-05 12:11 alexy Resolution open => fixed
2009-04-05 12:11 alexy Fixed in Version => 2.0