info.c revision 84f633d28fd1840520118fcc4ff7c726aeaa9184
/** @file
*
* VirtualBox Windows Guest Shared Folders
*
* File System Driver query and set information routines
*/
/*
* Copyright (C) 2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include "vbsf.h"
/** Macro for copying a SHFLSTRING file name into a FILE_DIRECTORY_INFORMATION structure. */
do { \
} while (0)
{
int vboxRC;
ULONG *pNextOffset = 0;
Log(("VBOXSF: MrxQueryDirectory: FileInformationClass %d, pVBoxFobx %p, hFile %RX64, pInfoBuffer %p\n",
if (!pVBoxFobx)
{
Log(("VBOXSF: MrxQueryDirectory: pVBoxFobx is invalid!\n"));
return STATUS_INVALID_PARAMETER;
}
if (!DirectoryName)
return STATUS_INVALID_PARAMETER;
if (DirectoryName->Length == 0)
Log(("VBOXSF: MrxQueryDirectory: DirectoryName = \\ (null string)\n"));
else
Log(("VBOXSF: MrxQueryDirectory: DirectoryName = %.*ls\n",
if (!Template)
return STATUS_INVALID_PARAMETER;
Log(("VBOXSF: MrxQueryDirectory: Template = \\ (null string)\n"));
else
Log(("VBOXSF: MrxQueryDirectory: Template = %.*ls\n",
Log(("VBOXSF: MrxQueryDirectory: Allocating cbHGCMBuffer = %d\n",
cbHGCMBuffer));
if (!pHGCMBuffer)
{
AssertFailed();
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Assume start from the beginning. */
index = 0;
{
Log(("VBOXSF: MrxQueryDirectory: Index specified %d\n",
index));
}
{
Log(("VBOXSF: MrxQueryDirectory: Query single entry\n"));
}
{
/* Calculate size required for parsed path: dir + \ + template + 0. */
if (DirectoryName->Length)
if (!ParsedPath)
{
goto end;
}
{
goto end;
}
cch = 0;
if (DirectoryName->Length)
{
/* Copy directory name into ParsedPath. */
/* Add terminating backslash. */
cch++;
}
/* Add terminating nul. */
/* cch is the number of chars without trailing nul. */
Log(("VBOXSF: MrxQueryDirectory: ParsedPath = %.*ls\n",
}
cFiles = 0;
/* vboxCallDirInfo requires a pointer to uint32_t. */
Log(("VBOXSF: MrxQueryDirectory: CallDirInfo: File = 0x%08x, Flags = 0x%08x, Index = %d, u32BufSize = %d\n",
Log(("VBOXSF: MrxQueryDirectory: u32BufSize after CallDirInfo = %d, rc = %Rrc\n",
u32BufSize, vboxRC));
switch (vboxRC)
{
case VINF_SUCCESS:
/* Nothing to do here. */
break;
case VERR_NO_TRANSLATION:
Log(("VBOXSF: MrxQueryDirectory: Host could not translate entry!\n"));
break;
case VERR_NO_MORE_FILES:
if (cFiles <= 0) /* VERR_NO_MORE_FILES appears at the first lookup when just returning the current dir ".".
* So we also have to check for the cFiles counter. */
{
/* Not an error, but we have to handle the return value. */
Log(("VBOXSF: MrxQueryDirectory: Host reported no more files!\n"));
{
/* First call. MSDN on FindFirstFile: "If the function fails because no matching files
* can be found, the GetLastError function returns ERROR_FILE_NOT_FOUND."
* So map this rc to file not found.
*/
}
else
{
/* Search continued. */
}
}
break;
case VERR_FILE_NOT_FOUND:
Log(("VBOXSF: MrxQueryDirectory: no such file!\n"));
break;
default:
Log(("VBOXSF: MrxQueryDirectory: Error %Rrc from CallDirInfo (cFiles=%d)!\n",
break;
}
if (Status != STATUS_SUCCESS)
goto end;
/* Verify that the returned buffer length is not greater than the original one. */
{
Log(("VBOXSF: MrxQueryDirectory: returned buffer size (%u) is invalid!!!\n",
u32BufSize));
goto end;
}
/* How many bytes remain in the buffer. */
Log(("VBOXSF: MrxQueryDirectory: cFiles=%d, Length=%d\n",
cFiles, cbHGCMBuffer));
{
if (cbEntry > cbHGCMBuffer)
{
Log(("VBOXSF: MrxQueryDirectory: Entry size (%d) exceeds the buffer size (%d)!!!\n",
cbEntry, cbHGCMBuffer));
goto end;
}
switch (FileInformationClass)
{
case FileDirectoryInformation:
{
Log(("VBOXSF: MrxQueryDirectory: FileDirectoryInformation\n"));
cbToCopy = sizeof(FILE_DIRECTORY_INFORMATION);
/* Struct already contains one char for null terminator. */
if (*pLengthRemaining >= cbToCopy)
{
pInfo->CreationTime.QuadPart = RTTimeSpecGetNtTime(&pDirEntry->Info.BirthTime); /* ridiculous name */
/* Align to 8 byte boundary */
}
else
{
}
break;
}
{
Log(("VBOXSF: MrxQueryDirectory: FileFullDirectoryInformation\n"));
cbToCopy = sizeof(FILE_FULL_DIR_INFORMATION);
/* Struct already contains one char for null terminator. */
if (*pLengthRemaining >= cbToCopy)
{
pInfo->CreationTime.QuadPart = RTTimeSpecGetNtTime(&pDirEntry->Info.BirthTime); /* ridiculous name */
/* Align to 8 byte boundary */
}
else
{
}
break;
}
{
Log(("VBOXSF: MrxQueryDirectory: FileBothDirectoryInformation\n"));
cbToCopy = sizeof(FILE_BOTH_DIR_INFORMATION);
/* struct already contains one char for null terminator */
if (*pLengthRemaining >= cbToCopy)
{
pInfo->CreationTime.QuadPart = RTTimeSpecGetNtTime(&pDirEntry->Info.BirthTime); /* ridiculous name */
Log(("VBOXSF: MrxQueryDirectory: FileBothDirectoryInformation cbAlloc = %x cbObject = %x\n",
Log(("VBOXSF: MrxQueryDirectory: FileBothDirectoryInformation cbToCopy = %d, name size=%d name len=%d\n",
Log(("VBOXSF: MrxQueryDirectory: FileBothDirectoryInformation File name %.*ls (DirInfo)\n",
Log(("VBOXSF: MrxQueryDirectory: FileBothDirectoryInformation File name %.*ls (DirEntry)\n",
/* Align to 8 byte boundary. */
}
else
{
}
break;
}
{
Log(("VBOXSF: MrxQueryDirectory: FileIdBothDirectoryInformation\n"));
cbToCopy = sizeof(FILE_ID_BOTH_DIR_INFORMATION);
/* struct already contains one char for null terminator */
if (*pLengthRemaining >= cbToCopy)
{
pInfo->CreationTime.QuadPart = RTTimeSpecGetNtTime(&pDirEntry->Info.BirthTime); /* ridiculous name */
Log(("VBOXSF: MrxQueryDirectory: FileIdBothDirectoryInformation cbAlloc = 0x%RX64 cbObject = 0x%RX64\n",
Log(("VBOXSF: MrxQueryDirectory: FileIdBothDirectoryInformation cbToCopy = %d, name size=%d name len=%d\n",
Log(("VBOXSF: MrxQueryDirectory: FileIdBothDirectoryInformation File name %.*ls (DirInfo)\n",
Log(("VBOXSF: MrxQueryDirectory: FileIdBothDirectoryInformation File name %.*ls (DirEntry)\n",
/* Align to 8 byte boundary. */
}
else
{
}
break;
}
case FileNamesInformation:
{
Log(("VBOXSF: MrxQueryDirectory: FileNamesInformation\n"));
cbToCopy = sizeof(FILE_NAMES_INFORMATION);
/* Struct already contains one char for null terminator. */
if (*pLengthRemaining >= cbToCopy)
{
Log(("VBOXSF: MrxQueryDirectory: FileNamesInformation: File name [%.*ls]\n",
/* Align to 8 byte boundary. */
}
else
{
}
break;
}
default:
Log(("VBOXSF: MrxQueryDirectory: Not supported FileInformationClass %d!\n",
goto end;
}
cbHGCMBuffer -= cbEntry;
Log(("VBOXSF: MrxQueryDirectory: %d bytes left in HGCM buffer\n",
cbHGCMBuffer));
if (*pLengthRemaining >= cbToCopy)
{
pInfoBuffer += cbToCopy;
*pLengthRemaining -= cbToCopy;
}
else
break;
break;
/* More left? */
if (cbHGCMBuffer <= 0)
break;
index++; /* File Index. */
cFiles--;
}
if (pNextOffset)
*pNextOffset = 0; /* Last pInfo->NextEntryOffset should be set to zero! */
end:
if (pHGCMBuffer)
if (ParsedPath)
Log(("VBOXSF: MrxQueryDirectory: Returned 0x%08X\n",
Status));
return Status;
}
{
Log(("VBOXSF: MrxQueryVolumeInfo: pInfoBuffer = %p, cbInfoBuffer = %d\n",
Log(("VBOXSF: MrxQueryVolumeInfo: vboxFobx = %p, Handle = 0x%RX64\n",
switch (FsInformationClass)
{
case FileFsVolumeInformation:
{
int vboxRC;
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsVolumeInformation\n"));
if (!pVBoxFobx)
{
Log(("VBOXSF: MrxQueryVolumeInfo: pVBoxFobx is NULL!\n"));
break;
}
pRootName++; /* Remove the leading backslash. */
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsVolumeInformation: Root name = %.*ls, %d bytes\n",
cbString += cbRootName;
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsVolumeInformation: cbToCopy %d, cbString %d\n",
if (cbInfoBuffer < cbToCopy)
{
break;
}
/* Query serial number. */
cbHGCMBuffer = sizeof(SHFLVOLINFO);
if (!pHGCMBuffer)
{
break;
}
if (vboxRC != VINF_SUCCESS)
{
break;
}
{
}
else
{
if (cbString > VBOX_VOLNAME_PREFIX_SIZE)
{
}
}
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsVolumeInformation: VolumeLabelLength %d\n",
break;
}
case FileFsLabelInformation:
{
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsLabelInformation\n"));
pRootName++; /* Remove the leading backslash. */
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsLabelInformation: Root name = %.*ls, %d bytes\n",
cbString += cbRootName;
if (cbInfoBuffer < cbToCopy)
{
break;
}
{
}
else
{
if (cbString > VBOX_VOLNAME_PREFIX_SIZE)
{
}
}
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsLabelInformation: VolumeLabelLength %d\n",
break;
}
case FileFsSizeInformation:
{
int vboxRC;
{
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsFullSizeInformation\n"));
cbToCopy = sizeof(FILE_FS_FULL_SIZE_INFORMATION);
}
else
{
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsSizeInformation\n"));
cbToCopy = sizeof(FILE_FS_SIZE_INFORMATION);
}
if (!pVBoxFobx)
{
Log(("VBOXSF: MrxQueryVolumeInfo: pVBoxFobx is NULL!\n"));
break;
}
if (cbInfoBuffer < cbToCopy)
{
break;
}
cbHGCMBuffer = sizeof(SHFLVOLINFO);
if (!pHGCMBuffer)
{
break;
}
if (vboxRC != VINF_SUCCESS)
{
break;
}
TotalAllocationUnits.QuadPart = pShflVolInfo->ullTotalAllocationBytes / pShflVolInfo->ulBytesPerAllocationUnit;
AvailableAllocationUnits.QuadPart = pShflVolInfo->ullAvailableAllocationBytes / pShflVolInfo->ulBytesPerAllocationUnit;
Log(("VBOXSF: MrxQueryVolumeInfo: AvailableAllocationUnits 0x%RX64\n", AvailableAllocationUnits.QuadPart));
{
}
else
{
}
break;
}
case FileFsDeviceInformation:
{
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsDeviceInformation: Type = %d\n",
NetRoot->DeviceType));
cbToCopy = sizeof(FILE_FS_DEVICE_INFORMATION);
if (cbInfoBuffer < cbToCopy)
{
break;
}
break;
}
{
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsAttributeInformation\n"));
cbString = sizeof(MRX_VBOX_FILESYS_NAME_U);
if (cbInfoBuffer < cbToCopy)
{
break;
}
{
sizeof(MRX_VBOX_FILESYS_NAME_U));
}
else
{
}
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsAttributeInformation: FileSystemNameLength %d\n",
break;
}
case FileFsControlInformation:
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsControlInformation: not supported\n"));
break;
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsObjectIdInformation: not supported\n"));
break;
case FileFsMaximumInformation:
Log(("VBOXSF: MrxQueryVolumeInfo: FileFsMaximumInformation: not supported\n"));
break;
default:
Log(("VBOXSF: MrxQueryVolumeInfo: Not supported FsInformationClass %d!\n",
break;
}
if (Status == STATUS_SUCCESS)
else if (Status == STATUS_BUFFER_TOO_SMALL)
{
Log(("VBOXSF: MrxQueryVolumeInfo: Insufficient buffer size %d, required %d\n",
cbInfoBuffer, cbToCopy));
}
Log(("VBOXSF: MrxQueryVolumeInfo: cbToCopy = %d, LengthRemaining = %d, Status = 0x%08X\n",
return Status;
}
{
int vboxRC = 0;
uint8_t *pHGCMBuffer = 0;
if (!pLengthRemaining)
{
Log(("VBOXSF: MrxQueryFileInfo: length pointer is NULL!\n"));
return STATUS_INVALID_PARAMETER;
}
Log(("VBOXSF: MrxQueryFileInfo: InfoBuffer = %p, Size = %d bytes, LenRemain = %d bytes\n",
if (!pVBoxFobx)
{
Log(("VBOXSF: MrxQueryFileInfo: pVBoxFobx is NULL!\n"));
return STATUS_INVALID_PARAMETER;
}
if (!pInfoBuffer)
{
Log(("VBOXSF: MrxQueryFileInfo: pInfoBuffer is NULL!\n"));
return STATUS_INVALID_PARAMETER;
}
{
Log(("VBOXSF: MrxQueryFileInfo: Directory -> Copy info retrieved during the create call\n"));
switch (FunctionalityRequested)
{
case FileBasicInformation:
{
Log(("VBOXSF: MrxQueryFileInfo: FileBasicInformation\n"));
cbToCopy = sizeof(FILE_BASIC_INFORMATION);
if (*pLengthRemaining >= cbToCopy)
{
Log(("VBOXSF: MrxQueryFileInfo: FileBasicInformation: File attributes: 0x%x\n",
pInfo->FileAttributes));
}
else
{
}
break;
}
case FileStandardInformation:
{
Log(("VBOXSF: MrxQueryFileInfo: FileStandardInformation\n"));
cbToCopy = sizeof(FILE_STANDARD_INFORMATION);
if (*pLengthRemaining >= cbToCopy)
else
break;
}
case FileNamesInformation:
{
Log(("VBOXSF: MrxQueryFileInfo: FileNamesInformation\n"));
cbToCopy = sizeof(FILE_NAMES_INFORMATION);
/* And size in bytes of the WCHAR name. */
if (*pLengthRemaining >= cbToCopy)
{
}
else
break;
}
case FileInternalInformation:
{
Log(("VBOXSF: MrxQueryFileInfo: FileInternalInformation\n"));
cbToCopy = sizeof(FILE_INTERNAL_INFORMATION);
if (*pLengthRemaining >= cbToCopy)
{
/* A 8-byte file reference number for the file. */
}
else
break;
}
case FileEaInformation:
{
Log(("VBOXSF: MrxQueryFileInfo: FileEaInformation\n"));
cbToCopy = sizeof(FILE_EA_INFORMATION);
if (*pLengthRemaining >= cbToCopy)
{
}
else
break;
}
{
Log(("VBOXSF: MrxQueryFileInfo: FileNetworkOpenInformation\n"));
cbToCopy = sizeof(FILE_NETWORK_OPEN_INFORMATION);
if (*pLengthRemaining >= cbToCopy)
{
}
else
break;
}
case FileStreamInformation:
Log(("VBOXSF: MrxQueryFileInfo: FileStreamInformation: not supported\n"));
goto end;
default:
Log(("VBOXSF: MrxQueryFileInfo: Not supported FunctionalityRequested %d!\n",
goto end;
}
}
else /* Entry is a file. */
{
if (!pHGCMBuffer)
return STATUS_INSUFFICIENT_RESOURCES;
if (vboxRC != VINF_SUCCESS)
{
goto end;
}
switch (FunctionalityRequested)
{
case FileBasicInformation:
{
Log(("VBOXSF: MrxQueryFileInfo: FileBasicInformation\n"));
cbToCopy = sizeof(FILE_BASIC_INFORMATION);
if (*pLengthRemaining >= cbToCopy)
{
Log(("VBOXSF: MrxQueryFileInfo: FileBasicInformation: File attributes = 0x%x\n",
pInfo->FileAttributes));
}
else
break;
}
case FileStandardInformation:
{
Log(("VBOXSF: MrxQueryFileInfo: FileStandardInformation\n"));
cbToCopy = sizeof(FILE_STANDARD_INFORMATION);
if (*pLengthRemaining >= cbToCopy)
{
else
}
else
break;
}
case FileNamesInformation:
{
Log(("VBOXSF: MrxQueryFileInfo: FileNamesInformation\n"));
cbToCopy = sizeof(FILE_NAMES_INFORMATION);
/* And size in bytes of the WCHAR name. */
if (*pLengthRemaining >= cbToCopy)
{
}
else
break;
}
case FileInternalInformation:
{
Log(("VBOXSF: MrxQueryFileInfo: FileInternalInformation\n"));
cbToCopy = sizeof(FILE_INTERNAL_INFORMATION);
if (*pLengthRemaining >= cbToCopy)
{
/* A 8-byte file reference number for the file. */
}
else
break;
}
case FileEaInformation:
{
Log(("VBOXSF: MrxQueryFileInfo: FileEaInformation\n"));
cbToCopy = sizeof(FILE_EA_INFORMATION);
if (*pLengthRemaining >= cbToCopy)
else
break;
}
{
Log(("VBOXSF: MrxQueryFileInfo: FileAttributeTagInformation\n"));
cbToCopy = sizeof(FILE_ATTRIBUTE_TAG_INFORMATION);
if (*pLengthRemaining >= cbToCopy)
{
pInfo->ReparseTag = 0;
}
else
break;
}
case FileEndOfFileInformation:
{
Log(("VBOXSF: MrxQueryFileInfo: FileEndOfFileInformation\n"));
cbToCopy = sizeof(FILE_END_OF_FILE_INFORMATION);
if (*pLengthRemaining >= cbToCopy)
else
break;
}
{
Log(("VBOXSF: MrxQueryFileInfo: FileAllocationInformation\n"));
cbToCopy = sizeof(FILE_ALLOCATION_INFORMATION);
if (*pLengthRemaining >= cbToCopy)
else
break;
}
{
Log(("VBOXSF: MrxQueryFileInfo: FileNetworkOpenInformation\n"));
cbToCopy = sizeof(FILE_NETWORK_OPEN_INFORMATION);
if (*pLengthRemaining >= cbToCopy)
{
}
else
break;
}
case FileStreamInformation:
Log(("VBOXSF: MrxQueryFileInfo: FileStreamInformation: not supported\n"));
goto end;
default:
Log(("VBOXSF: MrxQueryFileInfo: Not supported FunctionalityRequested %d!\n",
goto end;
}
}
if (Status == STATUS_SUCCESS)
{
if (*pLengthRemaining < cbToCopy)
{
/* This situation must be already taken into account by the above code. */
AssertMsgFailed(("VBOXSF: MrxQueryFileInfo: Length remaining is below 0! (%d - %d)!\n",
*pLengthRemaining, cbToCopy));
}
else
{
pInfoBuffer += cbToCopy;
*pLengthRemaining -= cbToCopy;
}
}
end:
if (Status == STATUS_BUFFER_TOO_SMALL)
{
Log(("VBOXSF: MrxQueryFileInfo: Buffer too small %d, required %d!\n",
*pLengthRemaining, cbToCopy));
}
if (pHGCMBuffer)
if (Status == STATUS_SUCCESS)
{
Log(("VBOXSF: MrxQueryFileInfo: Remaining length = %d\n",
*pLengthRemaining));
}
return Status;
}
{
int vboxRC;
Log(("VBOXSF: MrxSetFileInfo: pInfoBuffer %p\n",
pInfoBuffer));
switch (FunctionalityRequested)
{
case FileBasicInformation:
{
Log(("VBOXSF: MRxSetFileInfo: FileBasicInformation: CreationTime %RX64\n", pInfo->CreationTime.QuadPart));
Log(("VBOXSF: MRxSetFileInfo: FileBasicInformation: LastAccessTime %RX64\n", pInfo->LastAccessTime.QuadPart));
Log(("VBOXSF: MRxSetFileInfo: FileBasicInformation: LastWriteTime %RX64\n", pInfo->LastWriteTime.QuadPart));
Log(("VBOXSF: MRxSetFileInfo: FileBasicInformation: ChangeTime %RX64\n", pInfo->ChangeTime.QuadPart));
Log(("VBOXSF: MRxSetFileInfo: FileBasicInformation: FileAttributes %RX32\n", pInfo->FileAttributes));
/* When setting file attributes, a value of -1 indicates to the server that it MUST NOT change this attribute
* for all subsequent operations on the same file handle.
*/
{
}
{
}
{
}
{
}
cbBuffer = sizeof(SHFLFSOBJINFO);
if (!pHGCMBuffer)
{
AssertFailed();
return STATUS_INSUFFICIENT_RESOURCES;
}
Log(("VBOXSF: MrxSetFileInfo: FileBasicInformation: keeps %d %d %d %d\n",
pVBoxFobx->fKeepCreationTime, pVBoxFobx->fKeepLastAccessTime, pVBoxFobx->fKeepLastWriteTime, pVBoxFobx->fKeepChangeTime));
/* The properties, that need to be changed, are set to something other than zero */
{
}
{
}
{
}
{
}
if (pInfo->FileAttributes)
{
}
if (vboxRC != VINF_SUCCESS)
{
goto end;
}
else
{
/* Update our internal copy. Ignore zero fields! */
if (pInfo->FileAttributes)
}
break;
}
{
Log(("VBOXSF: MrxSetFileInfo: FileDispositionInformation: Delete = %d\n",
pInfo->DeleteFile));
else
break;
}
case FilePositionInformation:
{
Log(("VBOXSF: MrxSetFileInfo: FilePositionInformation: CurrentByteOffset = 0x%RX64. Unsupported!\n",
break;
}
{
Log(("VBOXSF: MrxSetFileInfo: FileAllocationInformation: new AllocSize = 0x%RX64, FileSize = 0x%RX64\n",
/* Check if the new allocation size changes the file size. */
{
/* Ignore this request and return success. Shared folders do not distinguish between
* AllocationSize and FileSize.
*/
}
else
{
/* Treat the request as a EndOfFile update. */
}
break;
}
case FileEndOfFileInformation:
{
Log(("VBOXSF: MrxSetFileInfo: FileEndOfFileInformation: new EndOfFile 0x%RX64, FileSize = 0x%RX64\n",
Log(("VBOXSF: MrxSetFileInfo: FileEndOfFileInformation: AllocSize = 0x%RX64, Status 0x%08X\n",
break;
}
case FileLinkInformation:
{
Log(("VBOXSF: MrxSetFileInfo: FileLinkInformation: ReplaceIfExists = %d, RootDirectory = 0x%x = [%.*ls]. Not implemented!\n",
pInfo->ReplaceIfExists, pInfo->RootDirectory, pInfo->FileNameLength / sizeof(WCHAR), pInfo->FileName));
break;
}
case FileRenameInformation:
{
Log(("VBOXSF: MrxSetFileInfo: FileRenameInformation: ReplaceIfExists = %d, RootDirectory = 0x%x = [%.*ls]\n",
pInfo->ReplaceIfExists, pInfo->RootDirectory, pInfo->FileNameLength / sizeof(WCHAR), pInfo->FileName));
break;
}
default:
Log(("VBOXSF: MrxSetFileInfo: Not supported FunctionalityRequested %d!\n",
break;
}
end:
if (pHGCMBuffer)
return Status;
}
{
Log(("VBOXSF: MRxSetFileInfoAtCleanup\n"));
return STATUS_SUCCESS;
}