Changeset 70889 in vbox for trunk/src/VBox/Runtime/r3
- Timestamp:
- Feb 7, 2018 12:33:10 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/nt/direnum-r3-nt.cpp
r70884 r70889 107 107 bool fObjDir = false; 108 108 #endif 109 if (hRelativeDir == ~(uintptr_t)0 && pvNativeRelative == NULL) 110 { 111 AssertMsg(pDir->fFlags & RTDIR_F_NO_FOLLOW /* Add FILE_OPEN_REPARSE_POINT and see how that works out (it better!). Need fallbacks for pre Vista. */, 112 ("Implement RTDIR_F_NO_FOLLOW!\n")); 113 rc = RTNtPathOpenDir(pszPathBuf, 114 FILE_LIST_DIRECTORY | FILE_READ_ATTRIBUTES | FILE_TRAVERSE | SYNCHRONIZE, 115 FILE_SHARE_READ | FILE_SHARE_WRITE, 116 FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT, 117 OBJ_CASE_INSENSITIVE, 118 &pDir->hDir, 119 #ifdef IPRT_WITH_NT_PATH_PASSTHRU 120 &fObjDir 121 #else 122 NULL 123 #endif 124 ); 125 } 126 else if (pvNativeRelative != NULL) 127 { 128 AssertMsg(pDir->fFlags & RTDIR_F_NO_FOLLOW /* Add FILE_OPEN_REPARSE_POINT and see how that works out (it better!). Need fallbacks for pre Vista. */, 129 ("Implement RTDIR_F_NO_FOLLOW!\n")); 130 rc = RTNtPathOpenDirEx((HANDLE)hRelativeDir, 131 (struct _UNICODE_STRING *)pvNativeRelative, 132 FILE_LIST_DIRECTORY | FILE_READ_ATTRIBUTES | FILE_TRAVERSE | SYNCHRONIZE, 133 FILE_SHARE_READ | FILE_SHARE_WRITE, 134 FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT, 135 OBJ_CASE_INSENSITIVE, 136 &pDir->hDir, 137 #ifdef IPRT_WITH_NT_PATH_PASSTHRU 138 &fObjDir 139 #else 140 NULL 141 #endif 142 143 ); 144 } 145 else 146 { 109 if (hRelativeDir != ~(uintptr_t)0 && pvNativeRelative == NULL) 110 { 111 /* Caller already opened it, easy! */ 147 112 pDir->hDir = (HANDLE)hRelativeDir; 148 113 rc = VINF_SUCCESS; 114 } 115 else 116 { 117 /* 118 * If we have to check for reparse points, this gets complicated! 119 */ 120 static int volatile g_fReparsePoints = -1; 121 uint32_t fOptions = FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT; 122 int fReparsePoints = g_fReparsePoints; 123 if (fReparsePoints != 0 && (pDir->fFlags & RTDIR_F_NO_FOLLOW)) 124 fOptions |= FILE_OPEN_REPARSE_POINT; 125 126 for (;;) 127 { 128 if (pvNativeRelative == NULL) 129 rc = RTNtPathOpenDir(pszPathBuf, 130 FILE_LIST_DIRECTORY | FILE_READ_ATTRIBUTES | FILE_TRAVERSE | SYNCHRONIZE, 131 FILE_SHARE_READ | FILE_SHARE_WRITE, 132 fOptions, 133 OBJ_CASE_INSENSITIVE, 134 &pDir->hDir, 135 #ifdef IPRT_WITH_NT_PATH_PASSTHRU 136 &fObjDir 137 #else 138 NULL 139 #endif 140 ); 141 else 142 rc = RTNtPathOpenDirEx((HANDLE)hRelativeDir, 143 (struct _UNICODE_STRING *)pvNativeRelative, 144 FILE_LIST_DIRECTORY | FILE_READ_ATTRIBUTES | FILE_TRAVERSE | SYNCHRONIZE, 145 FILE_SHARE_READ | FILE_SHARE_WRITE, 146 fOptions, 147 OBJ_CASE_INSENSITIVE, 148 &pDir->hDir, 149 #ifdef IPRT_WITH_NT_PATH_PASSTHRU 150 &fObjDir 151 #else 152 NULL 153 #endif 154 ); 155 if ( !(fOptions & FILE_OPEN_REPARSE_POINT) 156 || (rc != VINF_SUCCESS && rc != VERR_INVALID_PARAMETER) ) 157 break; 158 if (rc == VINF_SUCCESS) 159 { 160 if (fReparsePoints == -1) 161 g_fReparsePoints = 1; 162 163 /* 164 * We now need to check if we opened a symbolic directory link. 165 * (These can be enumerated, but contains only '.' and '..'.) 166 */ 167 FILE_ATTRIBUTE_TAG_INFORMATION TagInfo = { 0, 0 }; 168 IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER; 169 NTSTATUS rcNt = NtQueryInformationFile(pDir->hDir, &Ios, &TagInfo, sizeof(TagInfo), FileAttributeTagInformation); 170 AssertMsg(NT_SUCCESS(rcNt), ("%#x\n", rcNt)); 171 if (!NT_SUCCESS(rcNt)) 172 TagInfo.FileAttributes = TagInfo.ReparseTag = 0; 173 if (!(TagInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) 174 break; 175 176 NtClose(pDir->hDir); 177 pDir->hDir = RTNT_INVALID_HANDLE_VALUE; 178 179 if (TagInfo.ReparseTag == IO_REPARSE_TAG_SYMLINK) 180 { 181 rc = VERR_IS_A_SYMLINK; 182 break; 183 } 184 185 /* Reparse point that isn't a symbolic link, try follow the reparsing. */ 186 } 187 else if (fReparsePoints == -1) 188 g_fReparsePoints = fReparsePoints = 0; 189 fOptions &= ~FILE_OPEN_REPARSE_POINT; 190 } 191 149 192 } 150 193 if (RT_SUCCESS(rc))
Note:
See TracChangeset
for help on using the changeset viewer.