- Timestamp:
- May 4, 2019 3:44:42 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/SharedFolders/driver/info.cpp
r78369 r78381 1707 1707 /** 1708 1708 * Worker for VBoxMRxSetFileInfo. 1709 * 1710 * @todo Renaming files from the guest is _very_ expensive: 1711 * 52175 ns/call on the host 1712 * 844237 ns/call from the guest 1709 1713 */ 1710 1714 static NTSTATUS vbsfNtRename(IN PRX_CONTEXT RxContext, 1711 IN FILE_INFORMATION_CLASS FileInformationClass, 1712 IN PVOID pBuffer, 1713 IN ULONG BufferLength) 1715 IN PFILE_RENAME_INFORMATION pRenameInfo, 1716 IN ULONG cbInfo) 1714 1717 { 1715 NTSTATUS Status = STATUS_SUCCESS;1716 1717 1718 RxCaptureFcb; 1718 1719 RxCaptureFobx; 1719 1720 1720 PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot); 1721 PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx); 1722 PMRX_SRV_OPEN pSrvOpen = capFobx->pSrvOpen; 1723 1724 PFILE_RENAME_INFORMATION RenameInformation = (PFILE_RENAME_INFORMATION)RxContext->Info.Buffer; 1725 PUNICODE_STRING RemainingName = GET_ALREADY_PREFIXED_NAME(pSrvOpen, capFcb); 1726 1727 int vrc; 1728 PSHFLSTRING SrcPath = 0, DestPath = 0; 1729 ULONG flags; 1730 1731 RT_NOREF(FileInformationClass, pBuffer, BufferLength); 1732 1733 Assert(FileInformationClass == FileRenameInformation); 1734 1735 Log(("VBOXSF: vbsfNtRename: FileName = %.*ls\n", 1736 RenameInformation->FileNameLength / sizeof(WCHAR), &RenameInformation->FileName[0])); 1721 PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx); 1722 PMRX_SRV_OPEN pSrvOpen = capFobx->pSrvOpen; 1723 1724 /* Make sure we've got valid buffer and filename sizes: */ 1725 AssertReturn(cbInfo >= RT_UOFFSETOF(FILE_RENAME_INFORMATION, FileName), STATUS_INFO_LENGTH_MISMATCH); 1726 size_t const cbFilename = pRenameInfo->FileNameLength; 1727 AssertReturn(cbFilename < _64K - 2, STATUS_INVALID_PARAMETER); 1728 AssertReturn(cbInfo - RT_UOFFSETOF(FILE_RENAME_INFORMATION, FileName) >= cbFilename, STATUS_INFO_LENGTH_MISMATCH); 1729 1730 Log(("VBOXSF: vbsfNtRename: FileNameLength = %#x (%d), FileName = %.*ls\n", 1731 cbFilename, cbFilename, cbFilename / sizeof(WCHAR), &pRenameInfo->FileName[0])); 1737 1732 1738 1733 /* Must close the file before renaming it! */ 1739 1734 if (pVBoxFobx->hFile != SHFL_HANDLE_NIL) 1735 { 1736 Log(("VBOXSF: vbsfNtRename: Closing handle %#RX64...\n", pVBoxFobx->hFile)); 1740 1737 vbsfNtCloseFileHandle(pNetRootExtension, pVBoxFobx, VBoxMRxGetFcbExtension(capFcb)); 1741 1742 /* Mark it as renamed, so we do nothing during close */ 1738 } 1739 1740 /* Mark it as renamed, so we do nothing during close. */ 1741 /** @todo r=bird: Isn't this a bit premature? */ 1743 1742 SetFlag(pSrvOpen->Flags, SRVOPEN_FLAG_FILE_RENAMED); 1744 1743 1745 Log(("VBOXSF: vbsfNtRename: RenameInformation->FileNameLength = %d\n", RenameInformation->FileNameLength)); 1746 Status = vbsfNtShflStringFromUnicodeAlloc(&DestPath, RenameInformation->FileName, (uint16_t)RenameInformation->FileNameLength); 1747 if (Status != STATUS_SUCCESS) 1748 return Status; 1749 1750 Log(("VBOXSF: vbsfNtRename: Destination path = %.*ls\n", 1751 DestPath->u16Length / sizeof(WCHAR), &DestPath->String.ucs2[0])); 1752 1753 Log(("VBOXSF: vbsfNtRename: RemainingName->Length = %d\n", RemainingName->Length)); 1754 Status = vbsfNtShflStringFromUnicodeAlloc(&SrcPath, RemainingName->Buffer, RemainingName->Length); 1755 if (Status != STATUS_SUCCESS) 1756 { 1757 vbsfNtFreeNonPagedMem(DestPath); 1758 return Status; 1759 } 1760 1761 Log(("VBOXSF: vbsfNtRename: Source path = %.*ls\n", 1762 SrcPath->u16Length / sizeof(WCHAR), &SrcPath->String.ucs2[0])); 1763 1764 /* Call host. */ 1765 flags = pVBoxFobx->Info.Attr.fMode & RTFS_DOS_DIRECTORY ? SHFL_RENAME_DIR : SHFL_RENAME_FILE; 1766 if (RenameInformation->ReplaceIfExists) 1767 flags |= SHFL_RENAME_REPLACE_IF_EXISTS; 1768 1769 Log(("VBOXSF: vbsfNtRename: Calling VbglR0SfRename\n")); 1770 vrc = VbglR0SfRename(&g_SfClient, &pNetRootExtension->map, SrcPath, DestPath, flags); 1771 1772 vbsfNtFreeNonPagedMem(SrcPath); 1773 vbsfNtFreeNonPagedMem(DestPath); 1774 1775 Status = vbsfNtVBoxStatusToNt(vrc); 1776 if (vrc != VINF_SUCCESS) 1777 Log(("VBOXSF: vbsfNtRename: VbglR0SfRename failed with %Rrc\n", vrc)); 1778 1744 /* 1745 * Allocate a request embedding the destination string. 1746 */ 1747 NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES; 1748 size_t const cbReq = RT_UOFFSETOF(VBOXSFRENAMEWITHSRCBUFREQ, StrDstPath.String) + cbFilename + sizeof(RTUTF16); 1749 VBOXSFRENAMEWITHSRCBUFREQ *pReq = (VBOXSFRENAMEWITHSRCBUFREQ *)VbglR0PhysHeapAlloc((uint32_t)cbReq); 1750 if (pReq) 1751 { 1752 /* The destination path string. */ 1753 pReq->StrDstPath.u16Size = (uint16_t)(cbFilename + sizeof(RTUTF16)); 1754 pReq->StrDstPath.u16Length = (uint16_t)cbFilename; 1755 memcpy(&pReq->StrDstPath.String, pRenameInfo->FileName, cbFilename); 1756 pReq->StrDstPath.String.utf16[cbFilename / sizeof(RTUTF16)] = '\0'; 1757 1758 /* The source path string. */ 1759 PUNICODE_STRING pNtSrcPath = GET_ALREADY_PREFIXED_NAME(pSrvOpen, capFcb); 1760 uint16_t const cbSrcPath = pNtSrcPath->Length; 1761 PSHFLSTRING pShflSrcPath = (PSHFLSTRING)VbglR0PhysHeapAlloc(SHFLSTRING_HEADER_SIZE + cbSrcPath + sizeof(RTUTF16)); 1762 if (pShflSrcPath) 1763 { 1764 pShflSrcPath->u16Length = cbSrcPath; 1765 pShflSrcPath->u16Size = cbSrcPath + (uint16_t)sizeof(RTUTF16); 1766 memcpy(&pShflSrcPath->String, pNtSrcPath->Buffer, cbSrcPath); 1767 pShflSrcPath->String.utf16[cbSrcPath / sizeof(RTUTF16)] = '\0'; 1768 1769 /* 1770 * Call the host. 1771 */ 1772 uint32_t fRename = pVBoxFobx->Info.Attr.fMode & RTFS_DOS_DIRECTORY ? SHFL_RENAME_DIR : SHFL_RENAME_FILE; 1773 if (pRenameInfo->ReplaceIfExists) 1774 fRename |= SHFL_RENAME_REPLACE_IF_EXISTS; 1775 Log(("VBOXSF: vbsfNtRename: Calling VbglR0SfHostReqRenameWithSrcBuf fFlags=%#x SrcPath=%.*ls, DstPath=%.*ls\n", 1776 fRename, pShflSrcPath->u16Length / sizeof(RTUTF16), pShflSrcPath->String.utf16, 1777 pReq->StrDstPath.u16Size / sizeof(RTUTF16), pReq->StrDstPath.String.utf16)); 1778 int vrc = VbglR0SfHostReqRenameWithSrcBuf(pNetRootExtension->map.root, pReq, pShflSrcPath, fRename); 1779 if (RT_SUCCESS(vrc)) 1780 Status = STATUS_SUCCESS; 1781 else 1782 { 1783 Status = vbsfNtVBoxStatusToNt(vrc); 1784 Log(("VBOXSF: vbsfNtRename: VbglR0SfRename failed with %Rrc (Status=%#x)\n", vrc, Status)); 1785 } 1786 1787 VbglR0PhysHeapFree(pShflSrcPath); 1788 } 1789 VbglR0PhysHeapFree(pReq); 1790 } 1779 1791 Log(("VBOXSF: vbsfNtRename: Returned 0x%08X\n", Status)); 1780 1792 return Status; 1781 1793 } 1782 1783 1794 1784 1795 /** … … 1873 1884 #endif 1874 1885 1875 Status = vbsfNtRename(RxContext, FileRenameInformation,RxContext->Info.Buffer, RxContext->Info.Length);1886 Status = vbsfNtRename(RxContext, (PFILE_RENAME_INFORMATION)RxContext->Info.Buffer, RxContext->Info.Length); 1876 1887 break; 1877 1888 }
Note:
See TracChangeset
for help on using the changeset viewer.