HRESULT PrjNotificationCB()

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);
}