// Client.cpp: implementation of the CNetClient class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "netapp.h" #include "netdlg.h" #include "Client.h" #include "Server.h" static CODETEXT m_Command[] = { { COMMAND_C_STORE | COMMAND_REQUEST, "C-Store Request" }, { COMMAND_C_FIND | COMMAND_REQUEST, "C-Find Request" }, { COMMAND_C_GET | COMMAND_REQUEST, "C-Get Request" }, { COMMAND_C_MOVE | COMMAND_REQUEST, "C-Move Request" }, { COMMAND_C_CANCEL | COMMAND_REQUEST, "C-Cancel Request" }, { COMMAND_C_ECHO | COMMAND_REQUEST, "C-Echo Request" }, { COMMAND_N_REPORT | COMMAND_REQUEST, "N-Report Request" }, { COMMAND_N_GET | COMMAND_REQUEST, "N-Get Request" }, { COMMAND_N_SET | COMMAND_REQUEST, "N-Set Request" }, { COMMAND_N_ACTION | COMMAND_REQUEST, "N-Action Request" }, { COMMAND_N_CREATE | COMMAND_REQUEST, "N-Create Request" }, { COMMAND_N_DELETE | COMMAND_REQUEST, "N-Delete Request" }, { COMMAND_C_STORE | COMMAND_RESPONSE, "C-Store Response" }, { COMMAND_C_FIND | COMMAND_RESPONSE, "C-Find Response" }, { COMMAND_C_GET | COMMAND_RESPONSE, "C-Get Response" }, { COMMAND_C_MOVE | COMMAND_RESPONSE, "C-Move Response" }, { COMMAND_C_CANCEL | COMMAND_RESPONSE, "C-Cancel Response" }, { COMMAND_C_ECHO | COMMAND_RESPONSE, "C-Echo Response" }, { COMMAND_N_REPORT | COMMAND_RESPONSE, "N-Report Response" }, { COMMAND_N_GET | COMMAND_RESPONSE, "N-Get Response" }, { COMMAND_N_SET | COMMAND_RESPONSE, "N-Set Response" }, { COMMAND_N_ACTION | COMMAND_RESPONSE, "N-Action Response" }, { COMMAND_N_CREATE | COMMAND_RESPONSE, "N-Create Response" }, { COMMAND_N_DELETE | COMMAND_RESPONSE, "N-Delete Response" }, }; extern CNetApp theApp; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CNetClient::CNetClient(L_CHAR* pszPath, L_UINT32 nMode) : LDicomNet(pszPath, nMode) { m_pAssociate = NULL; m_pServer = NULL; m_strAddress = ""; m_nProcess = PROCESS_NONE; m_nStatus = DICOM_SUCCESS; m_nTime = 0; } CNetClient::~CNetClient() { Close(); } ////////////////////////////////////////////////////////////////////// // Utilities ////////////////////////////////////////////////////////////////////// L_INT CNetClient::Connect(CString strServerTitle, CString strServerAddress, L_UINT nServerPort, CString strClientTitle, L_UINT nClientPort, LDicomAssociate *pAssociate) { L_INT nResult; CNetAccept Accept; L_CHAR szAddress[NET_MAX_ADDRESS_SIZE+1]; L_UINT nPort; Close(); if(theApp.m_pDlg->m_SecurityMode == DICOM_SECURE_ISCL) { int n; n = MessageBox(theApp.m_pDlg->m_hWnd, "Warning, trying to connect to a non-ISCL Secure Server may cause problems.\nDo you wish to continue?", "Warning", MB_YESNO); if(n==IDNO) return DICOM_ERROR_NET_FAILURE; } if(theApp.m_pDlg->m_SecurityMode == DICOM_SECURE_TLS) { int n; n = MessageBox(theApp.m_pDlg->m_hWnd, "Warning, trying to connect to a non-TLS Secure Server may cause problems.\nDo you wish to continue?", "Warning", MB_YESNO); if(n==IDNO) return DICOM_ERROR_NET_FAILURE; } m_pAssociate = pAssociate; m_pAssociate->SetCalled((L_CHAR *)(LPCTSTR)strServerTitle); m_pAssociate->SetCalling((L_CHAR *)(LPCTSTR)strClientTitle); nResult = LDicomNet::Connect(NULL, 0, (L_CHAR *)(LPCTSTR)strServerAddress, nServerPort); if (nResult != DICOM_SUCCESS) { DisplayMessage("Connect", nResult, TVI_ROOT); return nResult; } nResult = GetHostInfo(szAddress, &nPort); if (nResult == DICOM_SUCCESS) { m_strAddress = szAddress; } else { m_strAddress = ""; } if (nClientPort != 0) { m_pServer = new CNetServer((L_CHAR*)(LPCTSTR) theApp.m_pDlg->m_strTempFilesFolder); if (m_pServer == NULL) { DisplayMessage("Listen", DICOM_ERROR_MEMORY, TVI_ROOT); return DICOM_ERROR_MEMORY; } Accept.m_strTitle = strServerTitle; Accept.m_strAddress = strServerAddress; Accept.m_strMask = ""; Accept.m_nPort = 0; Accept.m_nVerify = ACCEPT_VERIFY_TITLE | ACCEPT_VERIFY_ADDRESS; nResult = m_pServer->Listen(strClientTitle, nClientPort, 1, FALSE, &Accept, 1); if (nResult != DICOM_SUCCESS) { delete m_pServer; m_pServer = NULL; return nResult; } } return DICOM_SUCCESS; } L_INT CNetClient::Accept() { L_INT nResult; CNetServer *pServer; L_CHAR szAddress[NET_MAX_ADDRESS_SIZE+1]; L_UINT nPort; nResult = GetPeerInfo(szAddress, &nPort); if (nResult == DICOM_SUCCESS) { m_strAddress = szAddress; } else { m_strAddress = ""; } pServer = (CNetServer *)GetServer(); if (pServer != NULL) { nResult = pServer->Verify("", m_strAddress, "", FALSE); } else { nResult = DICOM_SUCCESS; } DisplayMessage("Accept", nResult, TVI_ROOT); return nResult; } L_VOID CNetClient::Close() { if (m_pServer != NULL) { delete m_pServer; m_pServer = NULL; } LDicomNet::Close(); m_strAddress = ""; } L_VOID CNetClient::StartProcess(L_INT nProcess) { m_nProcess = nProcess; m_nStatus = COMMAND_STATUS_PENDING; m_nTime = GetTickCount() / 1000; } L_VOID CNetClient::StopProcess() { m_nStatus = COMMAND_STATUS_SUCCESS; m_nTime = 0; } L_VOID CNetClient::InfoProcess(L_INT &nProcess, L_UINT16 &nStatus, L_UINT32 &nTime) { nProcess = m_nProcess; nStatus = m_nStatus; nTime = GetTickCount() / 1000 - m_nTime; } HTREEITEM CNetClient::DisplayMessage(CString strText, L_INT nError, HTREEITEM hParent) { HTREEITEM hItem; CString strError=""; if (theApp.m_pDlg == NULL) { return NULL; } if (nError != -1) { theApp.m_pDlg->ConvertError(nError, strError); strError = ": " + strError; } hItem = theApp.m_pDlg->m_Message.InsertItem(strText+strError, hParent, TVI_LAST); theApp.m_pDlg->m_Message.RedrawWindow(); if (hParent == TVI_ROOT) { theApp.m_pDlg->m_Message.SelectItem(hItem); } return hItem; } L_VOID CNetClient::DisplayTree(CTreeCtrl *pDlg, LDicomDS *pDS, HTREEITEM hParentTree, pDICOMELEMENT pParentElement, L_UINT16 nFlags) { pDICOMELEMENT pElement; pDICOMELEMENT pChild; pDICOMELEMENT pTemp; HTREEITEM hItem; CString strText; L_CHAR *pszText; L_CHAR szValue[256]; pDICOMTAG pTag; L_UINT32 nLength; if (theApp.m_pDlg == NULL) { return; } if ((pParentElement != NULL) && (pDS->ExistsElement(pParentElement) == FALSE)) { return; } if (nFlags & DISPLAY_TREE_DIRECTORY) { pElement = (pParentElement == NULL) ? pDS->GetFirstKey(NULL, TRUE) : pDS->GetChildKey(pParentElement); } else { pElement = (pParentElement == NULL) ? pDS->GetFirstElement(NULL, TRUE, FALSE) : pDS->GetChildElement(pParentElement, FALSE); } while (pElement != NULL) { if (nFlags & DISPLAY_TREE_DIRECTORY) { pszText = pDS->GetValueKey(pElement); strText = (pszText != NULL) ? pszText : "UNKNWON"; strText += ": "; pChild = pDS->GetChildElement(pElement, TRUE); if ((pChild != NULL) && (pszText != NULL)) { if (strcmp(pszText, "PATIENT") == 0) { pTemp = pDS->FindFirstElement(pChild, TAG_PATIENT_ID, TRUE); if (pTemp != NULL) { pszText = pDS->GetStringValue(pTemp, 0, 1); if (pszText != NULL) { strText += pszText; strText += " "; } } pTemp = pDS->FindFirstElement(pChild, TAG_PATIENT_NAME, TRUE); if (pTemp != NULL) { pszText = pDS->GetStringValue(pTemp, 0, 1); if (pszText != NULL) { strText += pszText; } } } else if (strcmp(pszText, "STUDY") == 0) { pTemp = pDS->FindFirstElement(pChild, TAG_STUDY_ID, TRUE); if (pTemp != NULL) { pszText = pDS->GetStringValue(pTemp, 0, 1); if (pszText != NULL) { strText += pszText; strText += " "; } } pTemp = pDS->FindFirstElement(pChild, TAG_PATIENT_NAME, TRUE); if (pTemp != NULL) { pszText = pDS->GetStringValue(pTemp, 0, 1); if (pszText != NULL) { strText += pszText; } } } else if (strcmp(pszText, "SERIES") == 0) { pTemp = pDS->FindFirstElement(pChild, TAG_SERIES_NUMBER, TRUE); if (pTemp != NULL) { pDS->GetConvertValue(pTemp, szValue); strText += szValue; strText += " "; } } else if (strcmp(pszText, "IMAGE") == 0) { pTemp = pDS->FindFirstElement(pChild, TAG_INSTANCE_NUMBER, TRUE); if (pTemp != NULL) { pDS->GetConvertValue(pTemp, szValue); strText += szValue; } } } } else { pTag = LDicomTag::Find(pElement->nTag); strText.Format("%04X:%04X - %s", GETGROUP(pElement->nTag), GETELEMENT(pElement->nTag), (pTag != NULL) ? pTag->pszName : "Unknown"); } if ((nFlags & DISPLAY_TREE_VALUES) && (pElement->nLength != 0) && (pElement->nLength != ELEMENT_LENGTH_MAX)) { nLength = pDS->GetConvertValue(pElement, NULL); if (nLength < sizeof(szValue)) { pDS->GetConvertValue(pElement, szValue); strText += ": "; strText += szValue; } } hItem = pDlg->InsertItem(strText, hParentTree, TVI_LAST); pDlg->SetItemData(hItem, (DWORD)pElement); if (nFlags & DISPLAY_TREE_DIRECTORY) { pDlg->SetItemState(hItem, TVIS_BOLD, TVIS_BOLD); } if (nFlags & DISPLAY_TREE_EXPANDED) { pDlg->SetItemState(hItem, TVIS_EXPANDED, TVIS_EXPANDED); } if (nFlags & DISPLAY_TREE_DIRECTORY) { if (pDS->GetChildKey(pElement) != NULL) { DisplayTree(pDlg, pDS, hItem, pElement, nFlags); } } else { if (pDS->GetChildElement(pElement, FALSE) != NULL) { DisplayTree(pDlg, pDS, hItem, pElement, nFlags & (~DISPLAY_TREE_DIRECTORY)); } } if (nFlags & DISPLAY_TREE_DIRECTORY) { pElement = pDS->GetNextKey(pElement, TRUE); } else { pElement = pDS->GetNextElement(pElement, nFlags & (~DISPLAY_TREE_VALUES), TRUE); } } } L_VOID CNetClient::DisplayAssociate(LDicomAssociate *pPDU, HTREEITEM hItem) { HTREEITEM hItem1; HTREEITEM hItem2; CString strText; CString strResult; L_INT i; L_INT j; L_INT n; L_INT m; L_UCHAR nID; pDICOMUID pUID; if (theApp.m_pDlg == NULL) { return; } strText.Format("Version: %u", pPDU->GetVersion()); theApp.m_pDlg->m_Message.InsertItem(strText, hItem, TVI_LAST); strText.Format("Called: %s", pPDU->GetCalled()); theApp.m_pDlg->m_Message.InsertItem(strText, hItem, TVI_LAST); strText.Format("Calling: %s", pPDU->GetCalling()); theApp.m_pDlg->m_Message.InsertItem(strText, hItem, TVI_LAST); pUID = LDicomUID::Find(pPDU->GetApplication()); strText.Format("Application Context: %s (%s)", (pUID != NULL) ? pUID->pszName : "", pPDU->GetApplication()); theApp.m_pDlg->m_Message.InsertItem(strText, hItem, TVI_LAST); n = pPDU->GetPresentationCount(); for (i = 0; i < n; i++) { nID = pPDU->GetPresentation(i); strResult = ""; if (pPDU->IsRequest() == FALSE) { switch (pPDU->GetResult(nID)) { case PDU_ACCEPT_RESULT_SUCCESS: strResult = "Acceptance"; break; case PDU_ACCEPT_RESULT_USER_REJECT: strResult = "User rejection"; break; case PDU_ACCEPT_RESULT_PROVIDER_REJECT: strResult = "No reason"; break; case PDU_ACCEPT_RESULT_ABSTRACT_SYNTAX: strResult = "Abstract syntax not supported"; break; case PDU_ACCEPT_RESULT_TRANSFER_SYNTAX: strResult = "Transfer syntaxes not supported"; break; default: strResult.Format("Unknown reason (%u)", pPDU->GetResult(nID)); break; } } strText.Format("Presentation Context: %u ", nID); hItem1 = theApp.m_pDlg->m_Message.InsertItem(strText+strResult, hItem, TVI_LAST); pUID = LDicomUID::Find(pPDU->GetAbstract(nID)); strText.Format("Abstract Syntax: %s (%s)", (pUID != NULL) ? pUID->pszName : "", pPDU->GetAbstract(nID)); theApp.m_pDlg->m_Message.InsertItem(strText, hItem1, TVI_LAST); m = pPDU->GetTransferCount(nID); for (j = 0; j < m; j++) { pUID = LDicomUID::Find(pPDU->GetTransfer(nID, j)); strText.Format("Transfer Syntax: %s (%s)", (pUID != NULL) ? pUID->pszName : "", pPDU->GetTransfer(nID, j)); theApp.m_pDlg->m_Message.InsertItem(strText, hItem1, TVI_LAST); } if (pPDU->IsRoleSelect(nID) != FALSE) { strText.Format("Role Select: %s - %s", (pPDU->GetUserRole(nID) == PDU_ROLE_NON_SUPPORT) ? "User Non Sepport" : "User Support", (pPDU->GetProviderRole(nID) == PDU_ROLE_NON_SUPPORT) ? "Provider Non Support" : "Provider Support"); theApp.m_pDlg->m_Message.InsertItem(strText, hItem1, TVI_LAST); } if (pPDU->GetLengthExtended(nID) != 0) { strText.Format("Extended Negotiation: %ld", pPDU->GetLengthExtended(nID)); theApp.m_pDlg->m_Message.InsertItem(strText, hItem1, TVI_LAST); } } hItem1 = theApp.m_pDlg->m_Message.InsertItem("User Information", hItem, TVI_LAST); if (pPDU->IsMaxLength()) { strText.Format("Maximum Length: %lu", pPDU->GetMaxLength()); theApp.m_pDlg->m_Message.InsertItem(strText, hItem1, TVI_LAST); } if (pPDU->IsImplementClass()) { pUID = LDicomUID::Find(pPDU->GetImplementClass()); strText.Format("Implementation Class: %s (%s)", (pUID != NULL) ? pUID->pszName : "", pPDU->GetImplementClass()); theApp.m_pDlg->m_Message.InsertItem(strText, hItem1, TVI_LAST); } if (pPDU->IsAsyncOperations()) { hItem2 = theApp.m_pDlg->m_Message.InsertItem("Asynchronous Operations", hItem1, TVI_LAST); strText.Format("Invoked Operations: %u", pPDU->GetInvokedOperations()); theApp.m_pDlg->m_Message.InsertItem(strText, hItem2, TVI_LAST); strText.Format("Performed Operations: %u", pPDU->GetPerformedOperations()); theApp.m_pDlg->m_Message.InsertItem(strText, hItem2, TVI_LAST); } if (pPDU->IsImplementVersion()) { strText.Format("Implementation Version: %s", pPDU->GetImplementVersion()); theApp.m_pDlg->m_Message.InsertItem(strText, hItem1, TVI_LAST); } n = pPDU->GetUserInfoCount(); for (i = 0; i < n; i++) { strText.Format("User Info: %u (%lu bytes)", pPDU->GetTypeUserInfo(i), pPDU->GetLengthUserInfo(i)); theApp.m_pDlg->m_Message.InsertItem(strText, hItem1, TVI_LAST); } theApp.m_pDlg->m_Message.RedrawWindow(); } L_VOID CNetClient::DeleteEmpty(LDicomDS *pDS, pDICOMELEMENT pParent) { pDICOMELEMENT pElement; pDICOMELEMENT pTemp; pElement = (pParent == NULL) ? pDS->GetFirstElement(NULL, TRUE, FALSE) : pDS->GetChildElement(pParent, FALSE); while (pElement != NULL) { if (pDS->GetChildElement(pElement, FALSE) != NULL) { DeleteEmpty(pDS, pElement); } pTemp = pDS->GetParentElement(pElement); if ((pElement->nTag == TAG_DIRECTORY_RECORD_SEQUENCE) || ((pElement->nTag == TAG_ITEM) && (pTemp != NULL) && (pTemp->nTag == TAG_DIRECTORY_RECORD_SEQUENCE)) || ((pElement->nLength != 0) && (pElement->nLength != ELEMENT_LENGTH_MAX)) || ((pElement->nLength == ELEMENT_LENGTH_MAX) && (pDS->GetChildElement(pElement, FALSE) != NULL))) { pElement = pDS->GetNextElement(pElement, TRUE, FALSE); } else { pTemp = pElement; pElement = pDS->GetNextElement(pElement, TRUE, FALSE); pDS->DeleteElement(pTemp); } } } // Unsupported Abstract and Transfer Syntaxes L_CHAR* UnsupportedUIDs[] = { // Abstract Syntaxes UID_BASIC_STUDY_NOTIFICATION_CLASS UID_APPLICATION_CONTEXT_NAME UID_MODALITY_PERFORMED_CLASS UID_MODALITY_PERFORMED_RETRIEVE_CLASS UID_MODALITY_PERFORMED_NOTIFICATION_CLASS UID_BASIC_FILM_SESSION_CLASS UID_BASIC_FILM_BOX_CLASS UID_BASIC_GRAYSCALE_IMAGE_BOX_CLASS UID_BASIC_COLOR_IMAGE_BOX_CLASS UID_REFERENCED_IMAGE_BOX_CLASS_RETIRED UID_BASIC_GRAYSCALE_PRINT_META_CLASS UID_REFERENCED_GRAYSCALE_PRINT_META_CLASS_RETIRED UID_PRINT_JOB_CLASS UID_BASIC_ANNOTATION_BOX_CLASS UID_PRINTER_CLASS UID_PRINTER_CONFIGURATION_RETRIEVAL_CLASS UID_PRINTER_INSTANCE UID_PRINTER_CONFIGURATION_RETRIEVAL_INSTANCE UID_BASIC_COLOR_PRINT_META_CLASS UID_REFERENCED_COLOR_PRINT_META_CLASS_RETIRED UID_VOI_LUT_BOX_CLASS_RETIRED UID_PRESENTATION_LUT_CLASS UID_IMAGE_OVERLAY_BOX_CLASS_RETIRED UID_BASIC_PRINT_IMAGE_OVERLAY_BOX_CLASS UID_PRINT_QUEUE_INSTANCE UID_PRINT_QUEUE_CLASS UID_PULL_PRINT_REQUEST_CLASS UID_PULL_STORED_PRINT_META_CLASS UID_PATIENT_ROOT_QUERY_FIND UID_PATIENT_ROOT_QUERY_MOVE UID_PATIENT_ROOT_QUERY_GET UID_STUDY_ROOT_QUERY_FIND UID_STUDY_ROOT_QUERY_MOVE UID_STUDY_ROOT_QUERY_GET UID_PATIENT_STUDY_QUERY_FIND UID_PATIENT_STUDY_QUERY_MOVE UID_PATIENT_STUDY_QUERY_GET UID_MODALITY_WORKLIST_FIND UID_PAPYRUS_3_IMPLICIT_VR_LITTLE_ENDIAN // Transfer Syntaxes UID_JPEG_EXTENDED_3_5, UID_JPEG_SPECTRAL_NONHIER_6_8, UID_JPEG_SPECTRAL_NONHIER_7_9, UID_JPEG_FULL_NONHIER_10_12, UID_JPEG_FULL_NONHIER_11_13, UID_JPEG_LOSSLESS_NONHIER_15, UID_JPEG_EXTENDED_HIER_16_18, UID_JPEG_EXTENDED_HIER_17_19, UID_JPEG_SPECTRAL_HIER_20_22, UID_JPEG_SPECTRAL_HIER_21_23, UID_JPEG_FULL_HIER_24_26, UID_JPEG_FULL_HIER_25_27, UID_JPEG_LOSSLESS_HIER_PROCESS_28, UID_JPEG_LOSSLESS_HIER_PROCESS_29, UID_JPEG_LS_LOSSLESS, UID_JPEG_LS_LOSSY }; L_BOOL CNetClient::IsSupported(L_CHAR* pszUID) const { int iCount = sizeof(UnsupportedUIDs) / sizeof(UnsupportedUIDs[0]); for (int i = 0; i < iCount; i++) if (lstrcmp(pszUID, UnsupportedUIDs[i]) == 0) return FALSE; if (LDicomUID::Find(pszUID) == NULL) return FALSE; return TRUE; } HTREEITEM CNetClient::FindDirectoryRecord(HTREEITEM hDirItem, L_UINT32 uTag, const L_CHAR* pszIdentifier) const { CTreeCtrl& DirCtrl = theApp.m_pDlg->m_Dir; LDicomDS* pDirDS = theApp.m_pDlg->m_pDS; pDICOMELEMENT pElement, pDR; HTREEITEM hCurrentItem = hDirItem; while (hCurrentItem) { pDR = (pDICOMELEMENT) DirCtrl.GetItemData(hCurrentItem); if (pDR != NULL && pDirDS->ExistsElement(pDR)) { pElement = pDirDS->GetChildElement(pDR, TRUE); if (pElement) { pElement = pDirDS->FindFirstElement(pElement, uTag, TRUE); if (pElement) { if (lstrcmp(pDirDS->GetStringValue(pElement, 0, 1), pszIdentifier) == 0) { pDirDS->FreeValue(pElement); return hCurrentItem; } } } } hCurrentItem = DirCtrl.GetNextItem(hCurrentItem, TVGN_NEXT); } return NULL; } L_VOID CNetClient::FillDirectoryRecord(LDicomDS& SrcDS, pDICOMELEMENT pDR) const { if (pDR == NULL) return; LDicomDS* pDirDS = theApp.m_pDlg->m_pDS; pDICOMELEMENT pDRElement; pDRElement = pDirDS->GetChildElement(pDR, TRUE); if (pDRElement == NULL) return; L_UINT32 uModule; L_CHAR* pszDRType = pDirDS->GetValueKey(pDR); if (lstrcmpi("PATIENT", pszDRType) == 0) { uModule = MODULE_PATIENT; } else if (lstrcmpi("STUDY", pszDRType) == 0) { uModule = MODULE_GENERAL_STUDY; } else if (lstrcmpi("SERIES", pszDRType) == 0) { uModule = MODULE_GENERAL_SERIES; } else if (lstrcmpi("IMAGE", pszDRType) == 0) { uModule = MODULE_GENERAL_IMAGE; } else { return; } pDICOMMODULE pModule; pModule = SrcDS.FindModule(uModule); if (pModule == NULL) return; pDICOMELEMENT pModuleElement, pElement; L_CHAR* pszValue; L_UINT32 uLength; for (L_UINT32 i = 0; i < pModule->nCount; i++) { pModuleElement = pModule->pElement[i]; if (pModuleElement->nLength != 0 && pModuleElement->nLength != ELEMENT_LENGTH_MAX) { uLength = SrcDS.GetConvertValue(pModuleElement, NULL); if (uLength > 0) { pszValue = new L_CHAR[uLength]; if (pszValue) { SrcDS.GetConvertValue(pModuleElement, pszValue); pElement = pDirDS->FindFirstElement(pDRElement, pModuleElement->nTag, TRUE); if (pElement == NULL) { pElement = pDirDS->InsertElement(pDRElement, FALSE, pModuleElement->nTag, pModuleElement->nVR, FALSE, 0); } if (pElement) { pDirDS->SetConvertValue(pElement, pszValue, 1); } delete [] pszValue; } SrcDS.FreeValue(pModuleElement); } } } if (uModule == MODULE_GENERAL_IMAGE) { pElement = pDirDS->FindFirstElement(pDRElement, TAG_SOP_INSTANCE_UID, TRUE); if (pElement == NULL) { pElement = pDirDS->InsertElement(pDRElement, FALSE, TAG_SOP_INSTANCE_UID, VR_UI, FALSE, 0); } if (pElement) { pDRElement = pElement; pElement = SrcDS.FindFirstElement(NULL, TAG_SOP_INSTANCE_UID, FALSE); if (pElement) { pszValue = SrcDS.GetStringValue(pElement, 0, 1); if (pszValue) { pDirDS->SetStringValue(pDRElement, pszValue, 1); SrcDS.FreeValue(pElement); } } } } } HTREEITEM CNetClient::InsertDirTreeDR(HTREEITEM hParentItem, pDICOMELEMENT pDR) const { if (pDR == NULL) return NULL; LDicomDS* pDirDS = theApp.m_pDlg->m_pDS; CString strItemText; L_CHAR* pszDRType, * pszValue; L_UINT32 uLength; pszDRType = pDirDS->GetValueKey(pDR); if (pszDRType == NULL) return NULL; strItemText = pszDRType; strItemText += ": "; pDICOMELEMENT pElement; pDICOMELEMENT pDRElement = pDirDS->GetChildElement(pDR, TRUE); if (pDRElement) { if (strcmpi("PATIENT", pszDRType) == 0) { pElement = pDirDS->FindFirstElement(pDRElement, TAG_PATIENT_ID, TRUE); if (pElement) { pszValue = pDirDS->GetStringValue(pElement, 0, 1); if (pszValue) { strItemText += pszValue; strItemText += " "; } pDirDS->FreeValue(pElement); } pElement = pDirDS->FindFirstElement(pDRElement, TAG_PATIENT_NAME, TRUE); if (pElement) { pszValue = pDirDS->GetStringValue(pElement, 0, 1); if (pszValue) { strItemText += pszValue; } pDirDS->FreeValue(pElement); } } else if (strcmpi("STUDY", pszDRType) == 0) { pElement = pDirDS->FindFirstElement(pDRElement, TAG_STUDY_ID, TRUE); if (pElement) { pszValue = pDirDS->GetStringValue(pElement, 0, 1); if (pszValue) { strItemText += pszValue; } pDirDS->FreeValue(pElement); } } else if (strcmpi("SERIES", pszDRType) == 0) { pElement = pDirDS->FindFirstElement(pDRElement, TAG_SERIES_NUMBER, TRUE); if (pElement) { uLength = pDirDS->GetConvertValue(pElement, NULL); if (uLength > 0) { pszValue = new L_CHAR[uLength]; if (pszValue) { pDirDS->GetConvertValue(pElement, pszValue); strItemText += pszValue; delete [] pszValue; } } pDirDS->FreeValue(pElement); } } else if (strcmpi("IMAGE", pszDRType) == 0) { pElement = pDirDS->FindFirstElement(pDRElement, TAG_INSTANCE_NUMBER, TRUE); if (pElement) { uLength = pDirDS->GetConvertValue(pElement, NULL); if (uLength > 0) { pszValue = new L_CHAR[uLength]; if (pszValue) { pDirDS->GetConvertValue(pElement, pszValue); strItemText += pszValue; delete [] pszValue; } } pDirDS->FreeValue(pElement); } } } CTreeCtrl& DirCtrl = theApp.m_pDlg->m_Dir; HTREEITEM hItem; hItem = DirCtrl.InsertItem(strItemText, (hParentItem == NULL) ? TVI_ROOT : hParentItem); DirCtrl.SetItemData(hItem, DWORD(pDR)); return hItem; } L_VOID CNetClient::SetIconImage(pDICOMELEMENT pImageDR, LDicomDS& SrcDS) const { LDicomDS* pDirDS = theApp.m_pDlg->m_pDS; if (pImageDR == NULL || pDirDS->ExistsElement(pImageDR) == FALSE) return; LBitmap Bitmap; pDICOMELEMENT pElement; DICOMIMAGE ImageInfo; L_INT32 nDestPhotometric= IMAGE_PHOTOMETRIC_MONOCHROME2; pElement = SrcDS.FindFirstElement(NULL, TAG_PIXEL_DATA, FALSE); if (pElement == NULL) return; if (SrcDS.GetInfoImage(pElement, &ImageInfo, 0) != DICOM_SUCCESS) return; if (SrcDS.GetImage( pElement, Bitmap.GetHandle(), sizeof(BITMAPHANDLE), 0, 0, ORDER_BGRORGRAY, DICOM_GETIMAGE_AUTO_APPLY_MODALITY_LUT| DICOM_GETIMAGE_AUTO_APPLY_VOI_LUT | DICOM_GETIMAGE_ALLOW_RANGE_EXPANSION, NULL, NULL) != DICOM_SUCCESS) return; switch(ImageInfo.nPhotometric) { case IMAGE_PHOTOMETRIC_MONOCHROME1: case IMAGE_PHOTOMETRIC_MONOCHROME2: nDestPhotometric= IMAGE_PHOTOMETRIC_MONOCHROME2; break; case IMAGE_PHOTOMETRIC_PALETTE_COLOR: nDestPhotometric= IMAGE_PHOTOMETRIC_PALETTE_COLOR; break; case IMAGE_PHOTOMETRIC_RGB: case IMAGE_PHOTOMETRIC_ARGB: case IMAGE_PHOTOMETRIC_CMYK: case IMAGE_PHOTOMETRIC_YBR_FULL_422: case IMAGE_PHOTOMETRIC_YBR_FULL: nDestPhotometric= IMAGE_PHOTOMETRIC_RGB; break; } pElement = pDirDS->InsertElement(pImageDR, TRUE, TAG_ICON_IMAGE_SEQUENCE, VR_SQ, TRUE, 0); if (pElement) { pElement = pDirDS->InsertElement(pElement, TRUE, TAG_ITEM, VR_OB, TRUE, 0); if (pElement) { pElement = pDirDS->InsertElement(pElement, TRUE, TAG_PIXEL_DATA, VR_OW, FALSE, 0); if (pElement) { pDirDS->SetImage( pElement, Bitmap.GetHandle(), IMAGE_COMPRESSION_NONE, nDestPhotometric, 0, 0, DICOM_SETIMAGE_AUTO_SET_VOI_LUT, NULL, NULL); } } } } ////////////////////////////////////////////////////////////////////// // CNetClient message handlers ////////////////////////////////////////////////////////////////////// L_VOID CNetClient::OnConnect(L_INT nError) { if(theApp.m_pDlg->m_SecurityMode == DICOM_SECURE_NONE) OnSecureLinkReady(nError); // else // AfxMessageBox("Raw connection ready"); } L_VOID CNetClient::OnClose(L_INT nError, LDicomNet *pNet) { m_nStatus = COMMAND_STATUS_SUCCESS; DisplayMessage("Close", nError, TVI_ROOT); } L_VOID CNetClient::OnReceive(L_INT nError, L_UCHAR nType, L_CHAR *pBuffer, L_UINT32 nBytes) { if (nError != DICOM_SUCCESS) { DisplayMessage("Receive", nError, TVI_ROOT); SendAbort(PDU_ABORT_SOURCE_USER, PDU_ABORT_REASON_UNKNOWN); return ; } if(nType == PDU_UNKNOWN) { SendAbort(PDU_ABORT_SOURCE_USER, PDU_ABORT_REASON_UNKNOWN); DisplayMessage("SendAbort", nError, TVI_ROOT); } } L_VOID CNetClient::OnSend(L_INT nError, L_UCHAR nType, L_UINT32 nBytes) { if (nError != DICOM_SUCCESS) { DisplayMessage("Send", nError, TVI_ROOT); SendAbort(PDU_ABORT_SOURCE_USER, PDU_ABORT_REASON_UNKNOWN); return ; } if(nType == PDU_UNKNOWN) { SendAbort(PDU_ABORT_SOURCE_USER, PDU_ABORT_REASON_UNKNOWN); DisplayMessage("SendAbort", nError, TVI_ROOT); } } L_VOID CNetClient::OnSecureLinkReady(L_UINT32 nError) { if (nError != DICOM_SUCCESS) { DisplayMessage("Connection failed ", nError, TVI_ROOT); } HTREEITEM hItem; if(theApp.m_pDlg->m_SecurityMode == DICOM_SECURE_ISCL) { CString str; L_CHAR authdata[128]; memset(authdata, 0, 128); L_UINT32 n = 128; GetPeerAuthDataISCL(authdata, &n); str.Format("Connected ISCL with peer identified by %s", authdata); DisplayMessage(str, nError, TVI_ROOT); // AfxMessageBox(str); } if(theApp.m_pDlg->m_SecurityMode == DICOM_SECURE_TLS) { CString str; L_CIPHERSUITE cipher; cipher = GetCiphersuiteTLS(); if(cipher == TLS_DHE_RSA_WITH_DES_CBC_SHA) str.Format("Connected TLS, cipher is TLS_DHE_RSA_WITH_DES_CBC_SHA"); if(cipher == TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) str.Format("Connected TLS, cipher is TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"); DisplayMessage(str, nError, TVI_ROOT); } m_nStatus = (nError == DICOM_SUCCESS) ? COMMAND_STATUS_SUCCESS : COMMAND_STATUS_PROCESSING_FAILURE; DisplayMessage("Connect", nError, TVI_ROOT); if (nError != DICOM_SUCCESS) { return; } if (m_pAssociate != NULL) { StartProcess(PROCESS_ASSOCIATE); nError = SendAssociateRequest(m_pAssociate); hItem = DisplayMessage("Send Associate Request", nError, TVI_ROOT); DisplayAssociate(m_pAssociate, hItem); if (nError != DICOM_SUCCESS) { StopProcess(); } } } L_VOID CNetClient::OnReceiveAssociateRequest(LDicomAssociate* pPDU) { CNetServer* pServer; L_INT nResult; pServer = (CNetServer*) GetServer(); if (pServer != NULL) { nResult = pServer->Verify(pPDU->GetCalled(), m_strAddress, pPDU->GetCalling(), TRUE); if (nResult != DICOM_SUCCESS) { DisplayMessage("Receive Associate Request", nResult, TVI_ROOT); // Reject the Association L_UCHAR nReason = PDU_REJECT_REASON_UNKNOWN; switch (nResult) { case DICOM_ERROR_USER_CLIENT_TITLE: nReason = PDU_REJECT_REASON_CALLING; break; case DICOM_ERROR_USER_SERVER_TITLE: nReason = PDU_REJECT_REASON_CALLED; break; } nResult = SendAssociateReject(PDU_REJECT_RESULT_PERMANENT, PDU_REJECT_SOURCE_USER, nReason); DisplayMessage("Send Associate Reject", nResult, TVI_ROOT); return; } } HTREEITEM hItem; hItem = DisplayMessage("Receive Associate Request", -1, TVI_ROOT); DisplayAssociate(pPDU, hItem); /* Send the Associate response */ LDicomAssociate Associate(FALSE); Associate.Reset(FALSE); // The Protocol Version Associate.SetVersion(1); // Titles of the Called and Calling AEs Associate.SetCalled(pServer == NULL ? NULL : (L_CHAR*)(LPCTSTR) pServer->GetTitle()); Associate.SetCalling(pPDU->GetCalling()); // The Application Context Name Associate.SetApplication(UID_APPLICATION_CONTEXT_NAME); L_INT nPresContCount = pPDU->GetPresentationCount(); L_UCHAR nPresContID; int i, j; // Presentation Contexts L_CHAR* pszAbstractSynName; for (i = 0; i < nPresContCount; i++) { nPresContID = pPDU->GetPresentation(i); pszAbstractSynName = pPDU->GetAbstract(nPresContID); Associate.AddPresentation(nPresContID, PDU_ACCEPT_RESULT_SUCCESS, pszAbstractSynName); // Do we support the Abstract Syntax of this Presentation Context? if (IsSupported(pszAbstractSynName)) { L_INT nTransSynCount = pPDU->GetTransferCount(nPresContID); L_CHAR* pszTransSynName; for (j = 0; j < nTransSynCount; j++) { pszTransSynName = pPDU->GetTransfer(nPresContID, j); // Select this Transfer Syntax if we support it if (IsSupported(pszTransSynName)) { Associate.AddTransfer(nPresContID, pszTransSynName); break; } } // Reject this Presentation Context if we didn't find a suitable Transfer Syntax if (j >= nTransSynCount) { Associate.SetResult(nPresContID, PDU_ACCEPT_RESULT_TRANSFER_SYNTAX); } } else { // Reject this Presentation Context because we don't support the Abstract Syntax Associate.SetResult(nPresContID, PDU_ACCEPT_RESULT_ABSTRACT_SYNTAX); } } // Maximum Length Application PDU if(pPDU->IsMaxLength()) { Associate.SetMaxLength(TRUE, pPDU->GetMaxLength()); } // Implementation Class UID Associate.SetImplementClass(TRUE, IMPLEMENTATION_CLASS_UID); // Implementation Version Name Associate.SetImplementVersion(TRUE, IMPLEMENTATION_VERSION_NAME); // Send the response nResult = SendAssociateAccept(&Associate); hItem = DisplayMessage("Send Associate Response", nResult, TVI_ROOT); DisplayAssociate(&Associate, hItem); } L_VOID CNetClient::OnReceiveAssociateAccept(LDicomAssociate *pPDU) { HTREEITEM hItem; m_nStatus = COMMAND_STATUS_SUCCESS; hItem = DisplayMessage("Receive Associate Accept", -1, TVI_ROOT); DisplayAssociate(pPDU, hItem); } L_VOID CNetClient::OnReceiveAssociateReject(L_UCHAR nResult, L_UCHAR nSource, L_UCHAR nReason) { CString strText; HTREEITEM hItem; m_nStatus = COMMAND_STATUS_SUCCESS; hItem = DisplayMessage("Receive Associate Reject", -1, TVI_ROOT); switch (nResult) { case PDU_REJECT_RESULT_PERMANENT: strText = "Result: Rejected permanent"; break; case PDU_REJECT_RESULT_TRANSIENT: strText = "Result: Rejected transient"; break; default: strText.Format("Result: %u", nResult); break; } DisplayMessage(strText, -1, hItem); switch (nSource) { case PDU_REJECT_SOURCE_USER: strText = "Source: Upper Layer service-user"; break; case PDU_REJECT_SOURCE_PROVIDER1: strText = "Source: Upper Layer service-provider (ASCE related function)"; break; case PDU_REJECT_SOURCE_PROVIDER2: strText = "Source: Upper Layer service-provider (Presentation related function)"; break; default: strText.Format("Source: %u", nSource); break; } DisplayMessage(strText, -1, hItem); switch (nSource) { case PDU_REJECT_SOURCE_USER: switch (nReason) { case PDU_REJECT_REASON_UNKNOWN: strText = "Reason: No reason given"; break; case PDU_REJECT_REASON_APPLICATION: strText = "Reason: Application context name not supported"; break; case PDU_REJECT_REASON_CALLING: strText = "Reason: Calling AE Title not recognized"; break; case PDU_REJECT_REASON_CALLED: strText = "Reason: Called AE Title not recognized"; break; default: strText.Format("Reason: %u", nReason); break; } break; case PDU_REJECT_SOURCE_PROVIDER1: switch (nReason) { case PDU_REJECT_REASON_UNKNOWN: strText = "Reason: No reason given"; break; case PDU_REJECT_REASON_VERSION: strText = "Reason: Protocol version not supported"; break; default: strText.Format("Reason: %u", nReason); break; } break; case PDU_REJECT_SOURCE_PROVIDER2: switch (nReason) { case PDU_REJECT_REASON_CONGESTION: strText = "Reason: Temporary congestion"; break; case PDU_REJECT_REASON_LIMIT: strText = "Reason: Local limit exceeded"; break; default: strText.Format("Reason: %u", nReason); break; } break; default: strText.Format("Reason: %u", nReason); break; } DisplayMessage(strText, -1, hItem); Close(); } L_VOID CNetClient::OnReceiveData(L_UCHAR nPresentationID, LDicomDS *pCS, LDicomDS *pDS) { HTREEITEM hItem; pDICOMELEMENT pElement; CString strText; CString strStatus; L_UINT16 nCommand; L_UINT16 nStatus=COMMAND_STATUS_SUCCESS; L_INT i; L_CHAR *p; L_INT16 *q; if (pCS == NULL) { return; } pElement = pCS->FindFirstElement(NULL, TAG_COMMAND_FIELD, TRUE); if (pElement != NULL) { q = pCS->GetShortValue(pElement, 0, 1); nCommand = *q; for (i = 0, p = NULL; i < sizeof(m_Command) / sizeof(m_Command[0]); i++) { if (nCommand == (L_UINT16)m_Command[i].nCode) { p = m_Command[i].pszText; break; } } if (p == NULL) { strText.Format("Unknown %u", nCommand); } else { strText = p; } } else { strText = "Unknown"; } pElement = pCS->FindFirstElement(NULL, TAG_STATUS, TRUE); if (pElement != NULL) { q = pCS->GetShortValue(pElement, 0, 1); if (q != NULL) { nStatus = *q; } } if (nCommand & COMMAND_RESPONSE) { m_nStatus = nStatus; } else if (nCommand == COMMAND_C_CANCEL) { m_nStatus = COMMAND_STATUS_CANCEL; } if ((m_nStatus == COMMAND_STATUS_PENDING) || (m_nStatus == COMMAND_STATUS_PENDING_WARNING)) { m_nTime = GetTickCount() / 1000; return; } if (nStatus == COMMAND_STATUS_SUCCESS) { strStatus = "Success"; } else { strStatus.Format("Error %04X", nStatus); } strText += ": "; strText += strStatus; hItem = DisplayMessage("Receive " + strText, -1, TVI_ROOT); strText.Format("Presentation ID: %u", nPresentationID); DisplayMessage(strText, -1, hItem); if (theApp.m_pDlg != NULL) { DisplayTree(&theApp.m_pDlg->m_Message, pCS, hItem, NULL, DISPLAY_TREE_VALUES); } } L_VOID CNetClient::OnReceiveReleaseRequest() { L_INT nResult; m_nStatus = COMMAND_STATUS_SUCCESS; DisplayMessage("Receive Release Request", -1, TVI_ROOT); nResult = SendReleaseResponse(); DisplayMessage("Send Release Response", nResult, TVI_ROOT); } L_VOID CNetClient::OnReceiveReleaseResponse() { m_nStatus = COMMAND_STATUS_SUCCESS; DisplayMessage("Receive Release Response", -1, TVI_ROOT); CloseForced(TRUE); } L_VOID CNetClient::OnReceiveAbort(L_UCHAR nSource, L_UCHAR nReason) { CString strText; HTREEITEM hItem; m_nStatus = COMMAND_STATUS_SUCCESS; hItem = DisplayMessage("Receive Abort", -1, TVI_ROOT); switch (nSource) { case PDU_ABORT_SOURCE_USER: strText = "Source: Upper Layer service-user"; break; case PDU_ABORT_SOURCE_PROVIDER: strText = "Source: Upper Layer service-provider"; break; default: strText.Format("Source: %u", nSource); break; } DisplayMessage(strText, -1, hItem); switch (nSource) { case PDU_ABORT_SOURCE_USER: strText.Format("Reason: %u", nReason); break; case PDU_ABORT_SOURCE_PROVIDER: switch (nReason) { case PDU_ABORT_REASON_UNKNOWN: strText = "Reason: Reason no specified"; break; case PDU_ABORT_REASON_UNRECOGNIZED: strText = "Reason: Unrecognized PDU"; break; case PDU_ABORT_REASON_UNEXPECTED: strText = "Reason: Unexpected PDU"; break; case PDU_ABORT_REASON_UNRECOGNIZED_PARAM: strText = "Reason: Unrecognized PDU parameter"; break; case PDU_ABORT_REASON_UNEXPECTED_PARAM: strText = "Reason: Unexpected PDU parameter"; break; case PDU_ABORT_REASON_INVALID_PARAM: strText = "Reason: Invalid PDU parameter value"; break; default: strText.Format("Reason: %u", nReason); break; } break; default: strText.Format("Reason: %u", nReason); break; } DisplayMessage(strText, -1, hItem); Close(); } L_VOID CNetClient::OnReceiveCStoreRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_CHAR *pszInstance, L_UINT16 nPriority, L_CHAR *pszMoveAE, L_UINT16 nMoveMessageID, LDicomDS *pDS) { m_nStatus = COMMAND_STATUS_SUCCESS; if (theApp.m_pDlg == NULL) { return; } pDICOMELEMENT pElement; if (pDS != NULL) { // Save the SOP Instance pElement = pDS->FindFirstElement(NULL, TAG_SOP_INSTANCE_UID, FALSE); if (pElement) { L_CHAR* pszInstanceUID = pDS->GetStringValue(pElement, 0, 1); if (pszInstanceUID) { CString strFile = theApp.m_pDlg->m_strFolder + pszInstanceUID; if (!theApp.m_pDlg->m_strExtension.IsEmpty()) { strFile += '.' + theApp.m_pDlg->m_strExtension; } L_UINT16 uRet = pDS->SaveDS((L_CHAR*)(LPCTSTR) strFile, DS_METAHEADER_PRESENT | DS_GROUP_LENGTHS); if (uRet == DICOM_SUCCESS) { CString strMessage = "SOP Instance was stored in \"" + strFile + '"'; DisplayMessage(strMessage, -1, TVI_ROOT); } } } L_INT nQueryMethod = theApp.m_pDlg->m_nQueryMethod; L_CHAR* pszPatientID = NULL; L_CHAR* pszStudyInstanceUID = NULL; L_CHAR* pszSeriesInstanceUID = NULL; L_CHAR* pszSOPInstanceUID = NULL; if (nQueryMethod != QUERY_STUDY_ROOT) { pElement = pDS->FindFirstElement(NULL, TAG_PATIENT_ID, FALSE); if (pElement) { pszPatientID = pDS->GetStringValue(pElement, 0, 1); } } pElement = pDS->FindFirstElement(NULL, TAG_STUDY_INSTANCE_UID, FALSE); if (pElement) { pszStudyInstanceUID = pDS->GetStringValue(pElement, 0, 1); } if (nQueryMethod != QUERY_PATIENT_STUDY_ONLY) { pElement = pDS->FindFirstElement(NULL, TAG_SERIES_INSTANCE_UID, FALSE); if (pElement) { pszSeriesInstanceUID = pDS->GetStringValue(pElement, 0, 1); } pElement = pDS->FindFirstElement(NULL, TAG_SOP_INSTANCE_UID, FALSE); if (pElement) { pszSOPInstanceUID = pDS->GetStringValue(pElement, 0, 1); } } CTreeCtrl& DirCtrl = theApp.m_pDlg->m_Dir; LDicomDS* pDirDS = theApp.m_pDlg->m_pDS; pDICOMELEMENT pImageDR = NULL; pDICOMELEMENT pDR; int iAbsent = 0; // (Ptn: 1), (Std: 2), (Srs: 3), (Img: 4) HTREEITEM hParentDirItem; HTREEITEM hDirItem = DirCtrl.GetNextItem(NULL, TVGN_CHILD); if (nQueryMethod != QUERY_STUDY_ROOT) { hDirItem = FindDirectoryRecord(hDirItem, TAG_PATIENT_ID, pszPatientID); } else { hDirItem = FindDirectoryRecord(hDirItem, TAG_STUDY_INSTANCE_UID, pszStudyInstanceUID); } if (hDirItem) { DirCtrl.SetItemState(hDirItem, 0, TVIS_BOLD); hParentDirItem = hDirItem; hDirItem = DirCtrl.GetChildItem(hDirItem); if (nQueryMethod != QUERY_STUDY_ROOT) { hDirItem = FindDirectoryRecord(hDirItem, TAG_STUDY_INSTANCE_UID, pszStudyInstanceUID); } else { hDirItem = FindDirectoryRecord(hDirItem, TAG_SERIES_INSTANCE_UID, pszSeriesInstanceUID); } if (hDirItem) { DirCtrl.SetItemState(hDirItem, 0, TVIS_BOLD); if (nQueryMethod != QUERY_PATIENT_STUDY_ONLY) { hParentDirItem = hDirItem; hDirItem = DirCtrl.GetChildItem(hDirItem); if (nQueryMethod != QUERY_STUDY_ROOT) { hDirItem = FindDirectoryRecord(hDirItem, TAG_SERIES_INSTANCE_UID, pszSeriesInstanceUID); } else { hDirItem = FindDirectoryRecord(hDirItem, TAG_SOP_INSTANCE_UID, pszSOPInstanceUID); } if (hDirItem) { DirCtrl.SetItemState(hDirItem, 0, TVIS_BOLD); if (nQueryMethod != QUERY_STUDY_ROOT) { hParentDirItem = hDirItem; hDirItem = DirCtrl.GetChildItem(hDirItem); hDirItem = FindDirectoryRecord(hDirItem, TAG_SOP_INSTANCE_UID, pszSOPInstanceUID); if (hDirItem) { DirCtrl.SetItemState(hDirItem, 0, TVIS_BOLD); pImageDR = (pDICOMELEMENT) DirCtrl.GetItemData(hDirItem); } else // New Image { iAbsent = 4; } } else { pImageDR = (pDICOMELEMENT) DirCtrl.GetItemData(hDirItem); } } else // New Series Or Image { iAbsent = (nQueryMethod != QUERY_STUDY_ROOT) ? 3 : 4; } } } else // New Study or Series { iAbsent = (nQueryMethod != QUERY_STUDY_ROOT) ? 2 : 3; } } else // New Patient or Study { iAbsent = (nQueryMethod != QUERY_STUDY_ROOT) ? 1 : 2; } if (iAbsent == 1) { pDR = pDirDS->InsertKey(NULL, "PATIENT", FALSE); FillDirectoryRecord(*pDS, pDR); if (pDR) DeleteEmpty(pDirDS, pDR); hParentDirItem = InsertDirTreeDR(NULL, pDR); } if (iAbsent == 2 && nQueryMethod == QUERY_STUDY_ROOT) { pDR = pDirDS->InsertKey(NULL, "STUDY", FALSE); FillDirectoryRecord(*pDS, pDR); if (pDR) DeleteEmpty(pDirDS, pDR); hParentDirItem = InsertDirTreeDR(NULL, pDR); } if ((iAbsent == 1 || iAbsent == 2) && nQueryMethod != QUERY_STUDY_ROOT && hParentDirItem != NULL) { pDR = (pDICOMELEMENT) DirCtrl.GetItemData(hParentDirItem); pDR = pDirDS->InsertKey(pDR, "STUDY", FALSE); FillDirectoryRecord(*pDS, pDR); if (pDR) DeleteEmpty(pDirDS, pDR); hParentDirItem = InsertDirTreeDR(hParentDirItem, pDR); } if (nQueryMethod != QUERY_PATIENT_STUDY_ONLY) { if ((iAbsent == 1 || iAbsent == 2 || iAbsent == 3) && hParentDirItem != NULL) { pDR = (pDICOMELEMENT) DirCtrl.GetItemData(hParentDirItem); pDR = pDirDS->InsertKey(pDR, "SERIES", FALSE); FillDirectoryRecord(*pDS, pDR); if (pDR) DeleteEmpty(pDirDS, pDR); hParentDirItem = InsertDirTreeDR(hParentDirItem, pDR); } if ((iAbsent == 1 || iAbsent == 2 || iAbsent == 3 || iAbsent == 4) && hParentDirItem != NULL) { pDR = (pDICOMELEMENT) DirCtrl.GetItemData(hParentDirItem); pImageDR = pDirDS->InsertKey(pDR, "IMAGE", FALSE); FillDirectoryRecord(*pDS, pImageDR); if (pImageDR) DeleteEmpty(pDirDS, pImageDR); InsertDirTreeDR(hParentDirItem, pImageDR); } if (pImageDR) { SetIconImage(pImageDR, *pDS); hDirItem = DirCtrl.GetSelectedItem(); if (hDirItem && pImageDR == (pDICOMELEMENT) DirCtrl.GetItemData(hDirItem)) { DirCtrl.EnsureVisible(hDirItem); theApp.m_pDlg->DisplayImage(pImageDR); } } } } L_INT nResult = SendCStoreResponse(nPresentationID, nMessageID, pszClass, pszInstance, COMMAND_STATUS_SUCCESS); DisplayMessage("Send C-Store Response", nResult, TVI_ROOT); } L_VOID CNetClient::OnReceiveCStoreResponse(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_CHAR *pszInstance, L_UINT16 nStatus) { } L_VOID CNetClient::OnReceiveCFindRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_UINT16 nPriority, LDicomDS *pDS) { } L_VOID CNetClient::OnReceiveCFindResponse(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_UINT16 nStatus, LDicomDS *pDS) { L_INT nResult; CString strText; CString strHexa; L_CHAR *pszKey; pDICOMELEMENT pElement; pDICOMELEMENT pParent; pDICOMELEMENT pTemp; L_UINT32 uCount; if (theApp.m_pDlg == NULL) { return; } if (theApp.m_pDlg->m_hItem == NULL) { pParent = NULL; } else { pParent = (pDICOMELEMENT)theApp.m_pDlg->m_Dir.GetItemData(theApp.m_pDlg->m_hItem); if ((pParent == NULL) || (theApp.m_pDlg->m_pDS->ExistsElement(pParent) == FALSE)) { return; } } if (pDS != NULL) { if (m_strRetrieveAEsMsg.IsEmpty()) { pElement = pDS->FindFirstElement(NULL, TAG_RETRIEVE_AE_TITLE, FALSE); if (pElement) { uCount = pDS->GetCountValue(pElement); if (uCount > 0) { L_CHAR* pszAETitle; L_CHAR* pszCalledAETitle = m_pAssociate->GetCalled(); m_strRetrieveAEsMsg = "The composite object instance(s) are not available " \ "from the \""; m_strRetrieveAEsMsg += pszCalledAETitle; m_strRetrieveAEsMsg += "\" AE we are connected to. They can be retrieved " \ "from the following DICOM AE(s):\n\n"; for (L_UINT32 i = 0; i < uCount; i++) { pszAETitle = pDS->GetStringValue(pElement, i, 1); if (pszAETitle) { if (lstrcmpi(pszCalledAETitle, pszAETitle) == 0) { break; } m_strRetrieveAEsMsg += pszAETitle; if (i != uCount - 1) { m_strRetrieveAEsMsg += '\n'; } } } pDS->FreeValue(pElement); if (i < uCount) { m_strRetrieveAEsMsg = ""; } } } } if (pParent != NULL) { pszKey = theApp.m_pDlg->m_pDS->GetValueKey(pParent); if (pszKey == NULL) { return; } } switch (theApp.m_pDlg->m_nQueryMethod) { case QUERY_PATIENT_ROOT: if (pParent == NULL) { strText = "PATIENT"; } else if (strcmp(pszKey, "PATIENT") == 0) { strText = "STUDY"; } else if (strcmp(pszKey, "STUDY") == 0) { strText = "SERIES"; } else if (strcmp(pszKey, "SERIES") == 0) { strText = "IMAGE"; } else { return; } break; case QUERY_STUDY_ROOT: if (pParent == NULL) { strText = "STUDY"; } else if (strcmp(pszKey, "STUDY") == 0) { strText = "SERIES"; } else if (strcmp(pszKey, "SERIES") == 0) { strText = "IMAGE"; } else { return; } break; case QUERY_PATIENT_STUDY_ONLY: if (pParent == NULL) { strText = "PATIENT"; } else if (strcmp(pszKey, "PATIENT") == 0) { strText = "STUDY"; } else { return; } break; } pElement = theApp.m_pDlg->m_pDS->InsertKey(pParent, (L_CHAR *)(LPCTSTR)strText, FALSE); if (pElement == NULL) { return; } nResult = theApp.m_pDlg->m_pDS->CopyDS(pElement, pDS, NULL); if (nResult != DICOM_SUCCESS) { theApp.m_pDlg->m_pDS->DeleteKey(pElement); return; } DeleteEmpty(theApp.m_pDlg->m_pDS, pElement); pElement = theApp.m_pDlg->m_pDS->GetChildElement(pElement, TRUE); while (pElement != NULL) { if ((GETGROUP(pElement->nTag) == 0x0000) || (GETGROUP(pElement->nTag) == 0x0002) || (pElement->nTag == TAG_QUERY_RETRIEVE_LEVEL)) { pTemp = theApp.m_pDlg->m_pDS->GetNextElement(pElement, TRUE, TRUE); theApp.m_pDlg->m_pDS->DeleteElement(pElement); pElement = pTemp; } else { pElement = theApp.m_pDlg->m_pDS->GetNextElement(pElement, TRUE, TRUE); } } } if (nStatus != COMMAND_STATUS_SUCCESS) { return; } if (theApp.m_pDlg->m_hItem != NULL) { theApp.m_pDlg->m_Dir.SetItemState(theApp.m_pDlg->m_hItem, 0, TVIS_BOLD); theApp.m_pDlg->m_Dir.SelectItem(theApp.m_pDlg->m_hItem); } DisplayTree(&theApp.m_pDlg->m_Dir, theApp.m_pDlg->m_pDS, (theApp.m_pDlg->m_hItem == NULL) ? TVI_ROOT : theApp.m_pDlg->m_hItem, pParent, DISPLAY_TREE_DIRECTORY | DISPLAY_TREE_EXPANDED); theApp.m_pDlg->m_Dir.RedrawWindow(); if (m_strRetrieveAEsMsg.IsEmpty() == FALSE) AfxMessageBox(m_strRetrieveAEsMsg, MB_OK | MB_ICONINFORMATION); } L_VOID CNetClient::OnReceiveCGetRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_UINT16 nPriority, LDicomDS *pDS) { } L_VOID CNetClient::OnReceiveCGetResponse(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_UINT16 nStatus, L_UINT16 nRemaining, L_UINT16 nCompleted, L_UINT16 nFailed, L_UINT16 nWarning, LDicomDS *pDS) { } L_VOID CNetClient::OnReceiveCMoveRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_UINT16 nPriority, L_CHAR *pszMoveAE, LDicomDS *pDS) { } L_VOID CNetClient::OnReceiveCMoveResponse(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_UINT16 nStatus, L_UINT16 nRemaining, L_UINT16 nCompleted, L_UINT16 nFailed, L_UINT16 nWarning, LDicomDS *pDS) { } L_VOID CNetClient::OnReceiveCCancelRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID) { } L_VOID CNetClient::OnReceiveCEchoRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass) { L_INT nResult = SendCEchoResponse(nPresentationID, nMessageID, pszClass,COMMAND_STATUS_SUCCESS); DisplayMessage("Send C-Echo Response", nResult, TVI_ROOT); } L_VOID CNetClient::OnReceiveCEchoResponse(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_UINT16 nStatus) { } L_VOID CNetClient::OnReceiveNReportRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_CHAR *pszInstance, L_UINT16 nEvent, LDicomDS *pDS) { } L_VOID CNetClient::OnReceiveNReportResponse(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_CHAR *pszInstance, L_UINT16 nStatus, L_UINT16 nEvent, LDicomDS *pDS) { } L_VOID CNetClient::OnReceiveNGetRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_CHAR *pszInstance, L_UINT32 *pnAttribute, L_UINT16 nCount) { } L_VOID CNetClient::OnReceiveNGetResponse(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_CHAR *pszInstance, L_UINT16 nStatus, LDicomDS *pDS) { } L_VOID CNetClient::OnReceiveNSetRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_CHAR *pszInstance, LDicomDS *pDS) { } L_VOID CNetClient::OnReceiveNSetResponse(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_CHAR *pszInstance, L_UINT16 nStatus, LDicomDS *pDS) { } L_VOID CNetClient::OnReceiveNActionRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_CHAR *pszInstance, L_UINT16 nAction, LDicomDS *pDS) { } L_VOID CNetClient::OnReceiveNActionResponse(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_CHAR *pszInstance, L_UINT16 nStatus, L_UINT16 nAction, LDicomDS *pDS) { } L_VOID CNetClient::OnReceiveNCreateRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_CHAR *pszInstance, LDicomDS *pDS) { } L_VOID CNetClient::OnReceiveNCreateResponse(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_CHAR *pszInstance, L_UINT16 nStatus, LDicomDS *pDS) { } L_VOID CNetClient::OnReceiveNDeleteRequest(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_CHAR *pszInstance) { } L_VOID CNetClient::OnReceiveNDeleteResponse(L_UCHAR nPresentationID, L_UINT16 nMessageID, L_CHAR *pszClass, L_CHAR *pszInstance, L_UINT16 nStatus) { } L_VOID CNetClient::OnReceiveUnknown(L_UCHAR nPresentationID, LDicomDS *pCS, LDicomDS *pDS) { /* You can process this message instead of processing "CNetClient::OnReceive" and check for nType == PDU_UNKNOWN. */ } L_UINT32 CNetClient::GetChallengeISCL(L_UINT64 *pChallenge, L_UINT64 nParameter) { *pChallenge = 0x0123456789ABCDE1; return 0; } L_UINT32 CNetClient::InternalAuthenticateISCL (L_UINT64 nChallenge, L_UINT64 *pResponse, L_UINT64 nParameter) { *pResponse = nChallenge + 1; return 0; } L_UINT32 CNetClient::ExternalAuthenticateISCL (L_UINT64 nChallenge, L_UINT64 nResponse, L_UINT64 nParameter) { if (nResponse == nChallenge + 1) return 0; else return 1; } L_VOID CNetClient::OnReceivedISCLPacket(L_INT nError, L_CHAR *pBuffer, L_UINT32 nBytes) { CString str, total; if(nError != 0) { str.Format("Error is: %d\n", nError); AfxMessageBox(str); // LDicomNet::OnReceivedISCLPacket(nError, pBuffer, nBytes); return; } str.Format("Recv ISCL packet, msg id: 0x%X\n", *((L_UINT32 *)&(pBuffer[4]))); total += str; str.Format("data length: %d\n", *((L_UINT32 *)&(pBuffer[8]))); total += str; str.Format("option: %d", *((L_UINT32 *)&(pBuffer[12]))); total += str; // AfxMessageBox(total); LDicomNet::OnReceivedISCLPacket(nError, pBuffer, nBytes); } L_INT CNetClient::OnPrivateKeyPassword(L_CHAR *pszPassword, L_INT nSize, L_INT uFlag) { int nLenPassword = 0; if ((theApp.strPrivateKeyPassword.GetLength() == 0) && (!theApp.bValidPrivateKeyPassword)) { CPasswordDlg dlg; dlg.m_strPassword = "test"; if (IDOK ==dlg.DoModal()) { theApp.strPrivateKeyPassword = dlg.m_strPassword; } } if (theApp.strPrivateKeyPassword.GetLength() > 0) { strncpy( pszPassword, (LPCSTR)theApp.strPrivateKeyPassword, nSize); nLenPassword = theApp.strPrivateKeyPassword.GetLength(); } return nLenPassword; }