# HG changeset patch # User Sebastien Jodogne # Date 1645610983 -3600 # Node ID 309fb4f027043f02e7861b9f44d2e7416d7e90e7 # Parent ce64d8995a41e2231ceea19bc8258305bda6430a fix signature of OrthancPluginIncomingCStoreInstanceFilter diff -r ce64d8995a41 -r 309fb4f02704 OrthancServer/Plugins/Engine/OrthancPlugins.cpp --- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Wed Feb 23 09:30:53 2022 +0100 +++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Wed Feb 23 11:09:43 2022 +0100 @@ -2260,8 +2260,9 @@ - uint16_t OrthancPlugins::FilterIncomingCStoreInstance(const DicomInstanceToStore& instance, - const Json::Value& simplified) + bool OrthancPlugins::FilterIncomingCStoreInstance(uint16_t& dimseStatus, + const DicomInstanceToStore& instance, + const Json::Value& simplified) { DicomInstanceFromCallback wrapped(instance); @@ -2271,20 +2272,26 @@ filter = pimpl_->incomingCStoreInstanceFilters_.begin(); filter != pimpl_->incomingCStoreInstanceFilters_.end(); ++filter) { - int32_t filterResult = (*filter) (reinterpret_cast(&wrapped)); - - if (filterResult >= 0 && filterResult <= 0xFFFF) - { - return static_cast(filterResult); + int32_t result = (*filter) (&dimseStatus, reinterpret_cast(&wrapped)); + + if (result == 0) + { + // The instance must be discarded + return false; + } + else if (result == 1) + { + // The instance is accepted + return true; } else { - // The callback is only allowed to answer uint16_t + // Error throw OrthancException(ErrorCode_Plugin); } } - return STATUS_Success; + return true; // By default, the instance is accepted } diff -r ce64d8995a41 -r 309fb4f02704 OrthancServer/Plugins/Engine/OrthancPlugins.h --- a/OrthancServer/Plugins/Engine/OrthancPlugins.h Wed Feb 23 09:30:53 2022 +0100 +++ b/OrthancServer/Plugins/Engine/OrthancPlugins.h Wed Feb 23 11:09:43 2022 +0100 @@ -273,8 +273,9 @@ virtual bool FilterIncomingInstance(const DicomInstanceToStore& instance, const Json::Value& simplified) ORTHANC_OVERRIDE; - virtual uint16_t FilterIncomingCStoreInstance(const DicomInstanceToStore& instance, - const Json::Value& simplified) ORTHANC_OVERRIDE; + virtual bool FilterIncomingCStoreInstance(uint16_t& dimseStatus, + const DicomInstanceToStore& instance, + const Json::Value& simplified) ORTHANC_OVERRIDE; OrthancPluginReceivedInstanceAction ApplyReceivedInstanceCallbacks(MallocMemoryBuffer& modified, const void* receivedDicomBuffer, diff -r ce64d8995a41 -r 309fb4f02704 OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h --- a/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Wed Feb 23 09:30:53 2022 +0100 +++ b/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Wed Feb 23 11:09:43 2022 +0100 @@ -29,6 +29,7 @@ * - Possibly register a callback for Storage Commitment SCP using ::OrthancPluginRegisterStorageCommitmentScpCallback(). * - Possibly register a callback to keep/discard/modify incoming DICOM instances using OrthancPluginRegisterReceivedInstanceCallback(). * - Possibly register a custom transcoder for DICOM images using OrthancPluginRegisterTranscoderCallback(). + * - Possibly register a callback to discard instances received through DICOM C-STORE using OrthancPluginRegisterIncomingCStoreInstanceFilter(). * -# void OrthancPluginFinalize(): * This function is invoked by Orthanc during its shutdown. The plugin * must free all its memory. @@ -7733,6 +7734,16 @@ * Note that the metadata information is not available * (i.e. GetInstanceMetadata() should not be used on "instance"). * + * @warning Your callback function will be called synchronously with + * the core of Orthanc. This implies that deadlocks might emerge if + * you call other core primitives of Orthanc in your callback (such + * deadlocks are particularly visible in the presence of other plugins + * or Lua scripts). It is thus strongly advised to avoid any call to + * the REST API of Orthanc in the callback. If you have to call + * other primitives of Orthanc, you should make these calls in a + * separate thread, passing the pending events to be processed + * through a message queue. + * * @param instance The received DICOM instance. * @return 0 to discard the instance, 1 to store the instance, -1 if error. * @ingroup Callback @@ -7753,21 +7764,10 @@ * DICOM instances received by Orthanc (either through the REST API * or through the DICOM protocol). * - * @warning Your callback function will be called synchronously with - * the core of Orthanc. This implies that deadlocks might emerge if - * you call other core primitives of Orthanc in your callback (such - * deadlocks are particularly visible in the presence of other plugins - * or Lua scripts). It is thus strongly advised to avoid any call to - * the REST API of Orthanc in the callback. If you have to call - * other primitives of Orthanc, you should make these calls in a - * separate thread, passing the pending events to be processed - * through a message queue. - * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param callback The callback. * @return 0 if success, other value if error. * @ingroup Callbacks - * @deprecated In new plugins, OrthancPluginRegisterReceivedInstanceCallback() should be used **/ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterIncomingDicomInstanceFilter( OrthancPluginContext* context, @@ -7785,20 +7785,33 @@ * Orthanc through C-STORE. * * Signature of a callback function that is triggered whenever - * Orthanc receives a new DICOM instance (through DICOM protocol), - * and that answers whether this DICOM instance should be accepted - * or discarded by Orthanc. If the instance is discarded, the callback - * can specify the C-STORE error code. + * Orthanc receives a new DICOM instance using DICOM C-STORE, and + * that answers whether this DICOM instance should be accepted or + * discarded by Orthanc. If the instance is discarded, the callback + * can specify the DIMSE error code answered by the Orthanc C-STORE + * SCP. * * Note that the metadata information is not available * (i.e. GetInstanceMetadata() should not be used on "instance"). * + * @warning Your callback function will be called synchronously with + * the core of Orthanc. This implies that deadlocks might emerge if + * you call other core primitives of Orthanc in your callback (such + * deadlocks are particularly visible in the presence of other plugins + * or Lua scripts). It is thus strongly advised to avoid any call to + * the REST API of Orthanc in the callback. If you have to call + * other primitives of Orthanc, you should make these calls in a + * separate thread, passing the pending events to be processed + * through a message queue. + * + * @param dimseStatus If the DICOM instance is discarded, + * DIMSE status to be sent by the C-STORE SCP of Orthanc * @param instance The received DICOM instance. - * @return 0 to accept the instance, any valid C-STORE error code - * to reject the instance, -1 if error. + * @return 0 to discard the instance, 1 to store the instance, -1 if error. * @ingroup Callback **/ typedef int32_t (*OrthancPluginIncomingCStoreInstanceFilter) ( + uint16_t* dimseStatus /* out */, const OrthancPluginDicomInstance* instance); @@ -7811,24 +7824,16 @@ * @brief Register a callback to filter incoming DICOM instances * received by Orthanc through C-STORE. * - * - * @warning Your callback function will be called synchronously with - * the core of Orthanc. This implies that deadlocks might emerge if - * you call other core primitives of Orthanc in your callback (such - * deadlocks are particularly visible in the presence of other plugins - * or Lua scripts). It is thus strongly advised to avoid any call to - * the REST API of Orthanc in the callback. If you have to call - * other primitives of Orthanc, you should make these calls in a - * separate thread, passing the pending events to be processed - * through a message queue. - * + * This function registers a custom callback to filter incoming + * DICOM instances received by Orthanc through the DICOM protocol. + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param callback The callback. * @return 0 if success, other value if error. * @ingroup Callbacks **/ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterIncomingCStoreInstanceFilter( - OrthancPluginContext* context, + OrthancPluginContext* context, OrthancPluginIncomingCStoreInstanceFilter callback) { _OrthancPluginIncomingCStoreInstanceFilter params; @@ -7851,12 +7856,22 @@ * transcoding and before filtering * (cf. OrthancPluginRegisterIncomingDicomInstanceFilter()). * - * @param modifiedDicomBuffer A buffer containing the modified DICOM (output) - * @param receivedDicomBuffer A buffer containing the received DICOM (input) - * @param receivedDicomBufferSize The size of the received DICOM (input) - * @param origin The origin of the DICOM instance (input) - * This buffer will be freed by the Orthanc core and must have been allocated - * using OrthancPluginCreateMemoryBuffer64(). + * @warning Your callback function will be called synchronously with + * the core of Orthanc. This implies that deadlocks might emerge if + * you call other core primitives of Orthanc in your callback (such + * deadlocks are particularly visible in the presence of other plugins + * or Lua scripts). It is thus strongly advised to avoid any call to + * the REST API of Orthanc in the callback. If you have to call + * other primitives of Orthanc, you should make these calls in a + * separate thread, passing the pending events to be processed + * through a message queue. + * + * @param modifiedDicomBuffer A buffer containing the modified DICOM (output). + * This buffer must be allocated using OrthancPluginCreateMemoryBuffer64() + * and will be freed by the Orthanc core. + * @param receivedDicomBuffer A buffer containing the received DICOM (input). + * @param receivedDicomBufferSize The size of the received DICOM (input). + * @param origin The origin of the DICOM instance (input). * @return `OrthancPluginReceivedInstanceAction_KeepAsIs` to accept the instance as is,
* `OrthancPluginReceivedInstanceAction_Modify` to store the modified DICOM contained in `modifiedDicomBuffer`,
* `OrthancPluginReceivedInstanceAction_Discard` to tell Orthanc to discard the instance. @@ -7878,16 +7893,17 @@ * @brief Register a callback to keep/discard/modify a DICOM instance received * by Orthanc from any source (C-STORE or REST API) * - * @warning Your callback function will be called synchronously with - * the core of Orthanc. This implies that deadlocks might emerge if - * you call other core primitives of Orthanc in your callback (such - * deadlocks are particularly visible in the presence of other plugins - * or Lua scripts). It is thus strongly advised to avoid any call to - * the REST API of Orthanc in the callback. If you have to call - * other primitives of Orthanc, you should make these calls in a - * separate thread, passing the pending events to be processed - * through a message queue. - * + * This function registers a custom callback to keep/discard/modify + * incoming DICOM instances received by Orthanc from any source + * (C-STORE or REST API). + * + * @warning Contrarily to + * OrthancPluginRegisterIncomingCStoreInstanceFilter() and + * OrthancPluginRegisterIncomingDicomInstanceFilter() that can be + * called by multiple plugins, + * OrthancPluginRegisterReceivedInstanceCallback() can only be used + * by one single plugin. + * * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param callback The callback. * @return 0 if success, other value if error. diff -r ce64d8995a41 -r 309fb4f02704 OrthancServer/Sources/IServerListener.h --- a/OrthancServer/Sources/IServerListener.h Wed Feb 23 09:30:53 2022 +0100 +++ b/OrthancServer/Sources/IServerListener.h Wed Feb 23 11:09:43 2022 +0100 @@ -45,8 +45,14 @@ virtual bool FilterIncomingInstance(const DicomInstanceToStore& instance, const Json::Value& simplified) = 0; - virtual uint16_t FilterIncomingCStoreInstance(const DicomInstanceToStore& instance, - const Json::Value& simplified) = 0; - + /** + * Returns "true" iff some DICOM instance received by the DICOM + * SCP is to be accepted. If the instance is discarded, + * "dimseStatus" must contain the DIMSE status that is sent back + * to the DICOM SCU. + **/ + virtual bool FilterIncomingCStoreInstance(uint16_t& dimseStatus, + const DicomInstanceToStore& instance, + const Json::Value& simplified) = 0; }; } diff -r ce64d8995a41 -r 309fb4f02704 OrthancServer/Sources/LuaScripting.cpp --- a/OrthancServer/Sources/LuaScripting.cpp Wed Feb 23 09:30:53 2022 +0100 +++ b/OrthancServer/Sources/LuaScripting.cpp Wed Feb 23 11:09:43 2022 +0100 @@ -32,8 +32,6 @@ #include "../../OrthancFramework/Sources/Logging.h" #include "../../OrthancFramework/Sources/Lua/LuaFunctionCall.h" -#include - #include @@ -936,8 +934,9 @@ return true; } - uint16_t LuaScripting::FilterIncomingCStoreInstance(const DicomInstanceToStore& instance, - const Json::Value& simplified) + bool LuaScripting::FilterIncomingCStoreInstance(uint16_t& dimseStatus, + const DicomInstanceToStore& instance, + const Json::Value& simplified) { static const char* NAME = "ReceivedCStoreInstanceFilter"; @@ -968,7 +967,7 @@ return static_cast(result); } - return STATUS_Success; + return true; } diff -r ce64d8995a41 -r 309fb4f02704 OrthancServer/Sources/LuaScripting.h --- a/OrthancServer/Sources/LuaScripting.h Wed Feb 23 09:30:53 2022 +0100 +++ b/OrthancServer/Sources/LuaScripting.h Wed Feb 23 11:09:43 2022 +0100 @@ -118,8 +118,9 @@ bool FilterIncomingInstance(const DicomInstanceToStore& instance, const Json::Value& simplifiedTags); - uint16_t FilterIncomingCStoreInstance(const DicomInstanceToStore& instance, - const Json::Value& simplified); + bool FilterIncomingCStoreInstance(uint16_t& dimseStatus, + const DicomInstanceToStore& instance, + const Json::Value& simplified); void Execute(const std::string& command); diff -r ce64d8995a41 -r 309fb4f02704 OrthancServer/Sources/ServerContext.cpp --- a/OrthancServer/Sources/ServerContext.cpp Wed Feb 23 09:30:53 2022 +0100 +++ b/OrthancServer/Sources/ServerContext.cpp Wed Feb 23 11:09:43 2022 +0100 @@ -554,9 +554,10 @@ if (dicom.GetOrigin().GetRequestOrigin() == Orthanc::RequestOrigin_DicomProtocol) { - uint16_t filterResult = it->GetListener().FilterIncomingCStoreInstance(dicom, simplifiedTags); - if (filterResult != 0x0000) + uint16_t filterResult = STATUS_Success; + if (!it->GetListener().FilterIncomingCStoreInstance(filterResult, dicom, simplifiedTags)) { + // The instance is to be discarded result.SetStatus(StoreStatus_FilteredOut); result.SetCStoreStatusCode(filterResult); break; diff -r ce64d8995a41 -r 309fb4f02704 OrthancServer/Sources/ServerContext.h --- a/OrthancServer/Sources/ServerContext.h Wed Feb 23 09:30:53 2022 +0100 +++ b/OrthancServer/Sources/ServerContext.h Wed Feb 23 11:09:43 2022 +0100 @@ -144,10 +144,11 @@ return context_.filterLua_.FilterIncomingInstance(instance, simplified); } - virtual uint16_t FilterIncomingCStoreInstance(const DicomInstanceToStore& instance, - const Json::Value& simplified) ORTHANC_OVERRIDE + virtual bool FilterIncomingCStoreInstance(uint16_t& dimseStatus, + const DicomInstanceToStore& instance, + const Json::Value& simplified) ORTHANC_OVERRIDE { - return context_.filterLua_.FilterIncomingCStoreInstance(instance, simplified); + return context_.filterLua_.FilterIncomingCStoreInstance(dimseStatus, instance, simplified); } };