| 1251 | } |
| 1252 | |
| 1253 | static NTSTATUS DOKAN_CALLBACK |
| 1254 | CryptMoveFile(LPCWSTR FileName, // existing file name |
| 1255 | LPCWSTR NewFileName, BOOL ReplaceIfExisting, |
| 1256 | PDOKAN_FILE_INFO DokanFileInfo) { |
| 1257 | |
| 1258 | /* |
| 1259 | |
| 1260 | If we are case insensitive, then we need special handling if you have a situation like as follows: |
| 1261 | |
| 1262 | files boo.txt and foo.txt already exitst, and you do |
| 1263 | |
| 1264 | move boo.txt FOO.TXT |
| 1265 | |
| 1266 | In that case, we need to move boo.txt to foo.txt, then rename foo.txt to FOO.TXT |
| 1267 | |
| 1268 | The second step (the rename) is called "repair" here. |
| 1269 | */ |
| 1270 | |
| 1271 | bool needRepair = false; |
| 1272 | |
| 1273 | /* |
| 1274 | If we are moving a file with an alternate data stream (besides the default "::$DATA" one) |
| 1275 | to a different directory, then we need to rename the stream(s) (the encrypted name) using |
| 1276 | the new IV for its new dir. |
| 1277 | |
| 1278 | There is no API for renaming streams, so the rename must be done by copy and delete. |
| 1279 | |
| 1280 | If the rename_streams_map has more than one (the default) stream, then we know to |
| 1281 | do this later. |
| 1282 | |
| 1283 | If we are operating on a (non-default) stream, then we don't need to do any of this. |
| 1284 | */ |
| 1285 | |
| 1286 | unordered_map<wstring, wstring> rename_streams_map; |
| 1287 | |
| 1288 | if (!GetContext()->GetConfig()->m_PlaintextNames) { |
| 1289 | wstring fromDir, toDir; |
| 1290 | get_file_directory(FileName, fromDir); |
| 1291 | get_file_directory(NewFileName, toDir); |
| 1292 | if (compare_names(GetContext(), fromDir.c_str(), toDir.c_str())) { |
| 1293 | wstring stream; |
| 1294 | bool is_stream = false; |
| 1295 | if (get_file_stream(FileName, NULL, &stream)) { |
| 1296 | is_stream = stream.length() > 0 && wcscmp(stream.c_str(), L":") && |
| 1297 | compare_names(GetContext(), stream.c_str(), L"::$DATA"); |
| 1298 | } |
| 1299 | if (!is_stream) |
| 1300 | CryptFindStreamsInternal(FileName, NULL, NULL, DokanFileInfo, |
| 1301 | StoreRenameStreamCallback, |
| 1302 | &rename_streams_map); |
| 1303 | } |
| 1304 | } |
| 1305 | |
| 1306 | NTSTATUS status = |
| 1307 | CryptMoveFileInternal(FileName, NewFileName, ReplaceIfExisting, |
| 1308 | DokanFileInfo, needRepair, false); |
| 1309 | |
| 1310 | if (GetContext()->IsCaseInsensitive() && status == 0 && needRepair) { |
nothing calls this directly
no test coverage detected