OSDN Git Service

Correct Extended Length Path Name handling on UNC
authorGreyMerlin <GreyMerlin@gmail.com>
Fri, 17 Aug 2018 00:12:22 +0000 (17:12 -0700)
committerGreyMerlin <GreyMerlin@gmail.com>
Fri, 17 Aug 2018 00:12:22 +0000 (17:12 -0700)
* Too many `\\` characters were being inserted when forming Extended
Length Path Names on UNC (i.e. Network Storage) devices.  This is a bug
in the original Poco library code

* Cleanup awkward code in `SuperComboBox.cpp` for detecting and
handling UNC file path names.

Externals/poco/Foundation/src/File_WIN32U.cpp
Src/Common/SuperComboBox.cpp

index 886a034..f394d03 100644 (file)
@@ -433,8 +433,12 @@ void FileImpl::convertPath(const std::string& utf8Path, std::wstring& utf16Path)
                        if (utf16Path.compare(0, 4, L"\\\\?\\", 4) != 0)
                        {
                                if (utf16Path[1] == '\\')
-                                       utf16Path.insert(0, L"\\\\?\\UNC\\", 8);
+                                       //      Starting with  "\\\\server\\etc\\etc..."
+                                       //      Form resulting "\\\\?\\UNC\\server\\etc\\etc..."
+                                       utf16Path.insert(1, L"\\?\\UNC", 6);
                                else
+                                       //      Starting with  "C:\\etc\\etc..."
+                                       //      Form resulting "\\\\?\\C:\\etc\\etc..."
                                        utf16Path.insert(0, L"\\\\?\\", 4);
                        }
                }
index 62878a0..d34b987 100644 (file)
@@ -480,9 +480,8 @@ void CSuperComboBox::OnGetDispInfo(NMHDR *pNotifyStruct, LRESULT *pResult)
                SHFILEINFO sfi = {0};
                CString sText;
                GetLBText(static_cast<int>(pDispInfo->ceItem.iItem), sText);
-               CString sDrive = sText.Left(3);
                bool isNetworkDrive = false;
-               if (sText.GetLength() >= 2 && (sText[1] == '\\') )
+               if (sText.GetLength() >= 2 && (sText[1] == L'\\'))
                {
                        if (sText.GetLength() > 4 && sText.Left(4) == L"\\\\?\\")
                                if (sText.GetLength() > 8 && sText.Left(8) == L"\\\\?\\UNC\\")
@@ -492,11 +491,15 @@ void CSuperComboBox::OnGetDispInfo(NMHDR *pNotifyStruct, LRESULT *pResult)
                        else
                                isNetworkDrive = true;
                }
-               if (!(isNetworkDrive || GetDriveType(sDrive) == DRIVE_REMOTE))
+               else
+               if (sText.GetLength() >= 3 && GetDriveType(sText.Left(3)) == DRIVE_REMOTE)
+                       isNetworkDrive = true;  // Drive letter, but mapped to Remote UNC device.
+
+               if (!isNetworkDrive)
                {
                        // The path is not a network path.
                        if (SHGetFileInfo(sText, 0, &sfi, sizeof(sfi), 
-                           SHGFI_SYSICONINDEX) != 0)
+                                                               SHGFI_SYSICONINDEX) != NULL)
                        {
                                pDispInfo->ceItem.iImage = sfi.iIcon;
                                pDispInfo->ceItem.iSelectedImage = sfi.iIcon;
@@ -505,11 +508,10 @@ void CSuperComboBox::OnGetDispInfo(NMHDR *pNotifyStruct, LRESULT *pResult)
                else
                {
                        // The path is a network path. 
-                       // try to get the index of a system image list icon with timeout.
-                       DWORD dwThreadId;
+                       // Try to get the index of a system image list icon, with 1-sec timeout.
                        HANDLE hThread = CreateThread(NULL, 0, SHGetFileInfoThread, 
-                               (VOID *)(LPCTSTR)sText, 0, &dwThreadId);
-                       if (hThread)
+                                                                                       (VOID *)(LPCTSTR)sText, 0, NULL);
+                       if (hThread != NULL)
                        {
                                DWORD dwResult = WaitForSingleObject(hThread, 1000);
                                if (dwResult == WAIT_OBJECT_0)