in ProjectedFSLib.Managed.API/VirtualizationInstance.cpp [1443:1627]
HRESULT PrjNotificationCB(_In_ const PRJ_CALLBACK_DATA* callbackData,
_In_ BOOLEAN isDirectory,
_In_ PRJ_NOTIFICATION notification,
_In_opt_ PCWSTR destinationFileName,
_Inout_ PRJ_NOTIFICATION_PARAMETERS* notificationParameters)
{
if (callbackData->InstanceContext != nullptr)
{
gcroot<VirtualizationInstance^>& pVirtualizationInstanceObj = *((gcroot<VirtualizationInstance^>*)callbackData->InstanceContext);
// Our pre-operation callback handlers return HResult, most of the post-operation callback
// handlers have void return type. Declare this for the ones that have a return code.
HResult notificationResult = HResult::Ok;
switch (notification)
{
case PRJ_NOTIFICATION_FILE_OPENED:
if (pVirtualizationInstanceObj->OnNotifyFileOpened != nullptr)
{
NotificationType notificationMask;
// The provider can deny the open by returning false.
if (!pVirtualizationInstanceObj->OnNotifyFileOpened(gcnew String(callbackData->FilePathName),
isDirectory != FALSE,
callbackData->TriggeringProcessId,
GetTriggeringProcessNameSafe(callbackData),
notificationMask))
{
notificationResult = HResult::AccessDenied;
}
else
{
notificationParameters->PostCreate.NotificationMask = static_cast<PRJ_NOTIFY_TYPES>(notificationMask);
}
}
break;
case PRJ_NOTIFICATION_NEW_FILE_CREATED:
if (pVirtualizationInstanceObj->OnNotifyNewFileCreated != nullptr)
{
NotificationType notificationMask;
pVirtualizationInstanceObj->OnNotifyNewFileCreated(gcnew String(callbackData->FilePathName),
isDirectory != FALSE,
callbackData->TriggeringProcessId,
GetTriggeringProcessNameSafe(callbackData),
notificationMask);
notificationParameters->PostCreate.NotificationMask = static_cast<PRJ_NOTIFY_TYPES>(notificationMask);
}
break;
case PRJ_NOTIFICATION_FILE_OVERWRITTEN:
if (pVirtualizationInstanceObj->OnNotifyFileOverwritten != nullptr)
{
NotificationType notificationMask;
pVirtualizationInstanceObj->OnNotifyFileOverwritten(gcnew String(callbackData->FilePathName),
isDirectory != FALSE,
callbackData->TriggeringProcessId,
GetTriggeringProcessNameSafe(callbackData),
notificationMask);
notificationParameters->PostCreate.NotificationMask = static_cast<PRJ_NOTIFY_TYPES>(notificationMask);
}
break;
case PRJ_NOTIFICATION_PRE_DELETE:
if (pVirtualizationInstanceObj->OnNotifyPreDelete != nullptr)
{
if (!pVirtualizationInstanceObj->OnNotifyPreDelete(gcnew String(callbackData->FilePathName),
isDirectory != FALSE,
callbackData->TriggeringProcessId,
GetTriggeringProcessNameSafe(callbackData)))
{
notificationResult = HResult::CannotDelete;
}
}
break;
case PRJ_NOTIFICATION_PRE_RENAME:
if (pVirtualizationInstanceObj->OnNotifyPreRename != nullptr)
{
if (!pVirtualizationInstanceObj->OnNotifyPreRename(gcnew String(callbackData->FilePathName),
gcnew String(destinationFileName),
callbackData->TriggeringProcessId,
GetTriggeringProcessNameSafe(callbackData)))
{
notificationResult = HResult::AccessDenied;
}
}
break;
case PRJ_NOTIFICATION_PRE_SET_HARDLINK:
if (pVirtualizationInstanceObj->OnNotifyPreCreateHardlink != nullptr)
{
if (!pVirtualizationInstanceObj->OnNotifyPreCreateHardlink(gcnew String(callbackData->FilePathName),
gcnew String(destinationFileName),
callbackData->TriggeringProcessId,
GetTriggeringProcessNameSafe(callbackData)))
{
notificationResult = HResult::AccessDenied;
}
}
break;
case PRJ_NOTIFICATION_FILE_RENAMED:
if (pVirtualizationInstanceObj->OnNotifyFileRenamed != nullptr)
{
NotificationType notificationMask;
pVirtualizationInstanceObj->OnNotifyFileRenamed(gcnew String(callbackData->FilePathName),
gcnew String(destinationFileName),
isDirectory != FALSE,
callbackData->TriggeringProcessId,
GetTriggeringProcessNameSafe(callbackData),
notificationMask);
notificationParameters->FileRenamed.NotificationMask = static_cast<PRJ_NOTIFY_TYPES>(notificationMask);
}
break;
case PRJ_NOTIFICATION_HARDLINK_CREATED:
if (pVirtualizationInstanceObj->OnNotifyHardlinkCreated != nullptr)
{
pVirtualizationInstanceObj->OnNotifyHardlinkCreated(gcnew String(callbackData->FilePathName),
gcnew String(destinationFileName),
callbackData->TriggeringProcessId,
GetTriggeringProcessNameSafe(callbackData));
}
break;
case PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_NO_MODIFICATION:
if (pVirtualizationInstanceObj->OnNotifyFileHandleClosedNoModification != nullptr)
{
pVirtualizationInstanceObj->OnNotifyFileHandleClosedNoModification(gcnew String(callbackData->FilePathName),
isDirectory != FALSE,
callbackData->TriggeringProcessId,
GetTriggeringProcessNameSafe(callbackData));
}
break;
case PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_FILE_MODIFIED:
if (pVirtualizationInstanceObj->OnNotifyFileHandleClosedFileModifiedOrDeleted != nullptr)
{
pVirtualizationInstanceObj->OnNotifyFileHandleClosedFileModifiedOrDeleted(gcnew String(callbackData->FilePathName),
isDirectory != FALSE,
true, // isFileModified
false, // isFileDeleted
callbackData->TriggeringProcessId,
GetTriggeringProcessNameSafe(callbackData));
}
break;
case PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_FILE_DELETED:
if (pVirtualizationInstanceObj->OnNotifyFileHandleClosedFileModifiedOrDeleted != nullptr)
{
pVirtualizationInstanceObj->OnNotifyFileHandleClosedFileModifiedOrDeleted(gcnew String(callbackData->FilePathName),
isDirectory != FALSE,
notificationParameters->FileDeletedOnHandleClose.IsFileModified != FALSE, // isFileModified
true, // isFileDeleted
callbackData->TriggeringProcessId,
GetTriggeringProcessNameSafe(callbackData));
}
break;
case PRJ_NOTIFICATION_FILE_PRE_CONVERT_TO_FULL:
if (pVirtualizationInstanceObj->OnNotifyFilePreConvertToFull != nullptr)
{
if (!pVirtualizationInstanceObj->OnNotifyFilePreConvertToFull(gcnew String(callbackData->FilePathName),
callbackData->TriggeringProcessId,
GetTriggeringProcessNameSafe(callbackData)))
{
notificationResult = HResult::AccessDenied;
}
}
break;
default:
// Unexpected notification type
break;
}
return static_cast<HRESULT>(notificationResult);
}
return HRESULT_FROM_WIN32(ERROR_INTERNAL_ERROR);
}