Variable Object::CreateVariable(const NodeId& newVariableId, const QualifiedName& browseName, const Variant& value) { // Creating new node for object AddNodesItem newNodeRequest; newNodeRequest.BrowseName = browseName; newNodeRequest.RequestedNewNodeId = newVariableId; newNodeRequest.Class = NodeClass::Variable; newNodeRequest.ParentNodeId = GetId(); newNodeRequest.ReferenceTypeId = ObjectId::HasProperty; newNodeRequest.TypeDefinition = NodeId(); VariableAttributes attrs; attrs.Description = LocalizedText(browseName.Name); attrs.DisplayName = LocalizedText(browseName.Name); attrs.Value = value; attrs.Type = OpcUa::VariantTypeToDataType(value.Type()); newNodeRequest.Attributes = attrs; NodeManagementServices::SharedPtr nodes = GetServices()->NodeManagement(); std::vector<AddNodesResult> newNode = nodes->AddNodes({newNodeRequest}); if (newNode.size() != 1) { throw std::runtime_error("opcua_model| Server returned wrong number new nodes results."); } OpcUa::CheckStatusCode(newNode[0].Status); Variable newVariable(GetServices()); newVariable.Id = newNode[0].AddedNodeId; newVariable.BrowseName = browseName; newVariable.DisplayName = attrs.Description; newVariable.DataType = value.Type(); newVariable.TypeId = newNodeRequest.TypeDefinition; return newVariable; }
bool BXServicesManager::GetServicesIds(std::vector<std::string>& servicesIdsVec) { BXBoxeeServices services; GetServices(services); int numOfServices = services.GetNumOfServices(); if(numOfServices < 1) { LOG(LOG_LEVEL_ERROR,"BXServicesManager::GetServicesIds - Call to GetServices returned [ServicesListSize=%d] (serv)",numOfServices); return false; } for(int i=0; i<numOfServices; i++) { BXObject obj = services.GetService(i); servicesIdsVec.push_back(obj.GetID()); } LOG(LOG_LEVEL_DEBUG,"BXServicesManager::GetServicesIds - Going to return [servicesIdsVecSize=%d] (serv)",servicesIdsVec.size()); return true; }
bool BXServicesManager::GetServices(std::vector<BXServicesItem>& servicesVec) { BXBoxeeServices services; GetServices(services); int numOfServices = services.GetNumOfServices(); if(numOfServices < 1) { LOG(LOG_LEVEL_ERROR,"BXServicesManager::GetServices - Call to GetServices returned [ServicesListSize=%d] (serv)",numOfServices); return false; } for(int i=0; i<numOfServices; i++) { BXObject obj = services.GetService(i); std::string type = obj.GetType(); std::string id = obj.GetID(); std::string name = obj.GetValue(MSG_KEY_NAME); BXServicesItem servicesItem(type,id,name); servicesVec.push_back(servicesItem); } LOG(LOG_LEVEL_DEBUG,"BXServicesManager::GetServices - Going to return [ServicesListSize=%d] (serv)",servicesVec.size()); return true; }
AddNodesItem Object::CreateObjectCopy(const NodeId& parentId, const ReferenceDescription& ref) { const NodeId& nodeId = ref.TargetNodeId; ReadParameters readParams; readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::DisplayName)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::Description)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::WriteMask)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::UserWriteMask)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::BrowseName)); std::vector<DataValue> values = GetServices()->Attributes()->Read(readParams); ObjectAttributes attrs; attrs.DisplayName = values[0].Value.As<LocalizedText>(); attrs.Description = values[1].Value.As<LocalizedText>(); attrs.WriteMask = values[2].Value.As<uint32_t>(); attrs.UserWriteMask = values[3].Value.As<uint32_t>(); AddNodesItem newNode; newNode.BrowseName = values[4].Value.As<QualifiedName>(); newNode.Class = NodeClass::Object; newNode.ParentNodeId = parentId; newNode.ReferenceTypeId = ref.ReferenceTypeId; newNode.TypeDefinition = ref.TargetNodeTypeDefinition; newNode.Attributes = attrs; return newNode; }
Variable Object::GetVariable(const RelativePath& relativePath) const { OpcUa::BrowsePath browsePath; browsePath.StartingNode = GetId(); browsePath.Path = relativePath; OpcUa::TranslateBrowsePathsParameters params; params.BrowsePaths.push_back(browsePath); const std::vector<OpcUa::BrowsePathResult>& result = GetServices()->Views()->TranslateBrowsePathsToNodeIds(params); if (result.size() != 1) throw std::runtime_error("object_model| Server returned more than one browse paths on TranslateBrowsePathsToNodeIds request."); const OpcUa::BrowsePathResult& resultPath = result.back(); OpcUa::CheckStatusCode(resultPath.Status); if (resultPath.Targets.size() != 1) throw std::runtime_error("object_model| Server returned too many target elements on TranslateBrowsePathsToNodeIds request."); return Variable(resultPath.Targets.back().Node, GetServices()); }
Object Object::CreateObject(const NodeId& newNodeId, const NodeId& parentNode, const NodeId& typeId, const QualifiedName& browseName, const std::string& displayName) { Object object(GetServices()); object.Id = InstantiateType(newNodeId, parentNode, typeId, NodeClass::Object, browseName, displayName); object.BrowseName = browseName; object.DisplayName = LocalizedText(displayName); return object; }
DataValue Variable::GetValue() const { ReadParameters params; params.AttributesToRead.push_back(AttributeValueID(GetID(), AttributeID::VALUE)); const std::vector<DataValue> result = GetServices()->Attributes()->Read(params); if (result.size() != 1) { throw std::runtime_error("Cannot read variable value. Server returned invalid number of values."); } return result.front(); }
INT_PTR CALLBACK ServicesPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { LV_COLUMN column; TCHAR szTemp[256]; DWORD dwStyle; UNREFERENCED_PARAMETER(lParam); UNREFERENCED_PARAMETER(wParam); switch (message) { case WM_INITDIALOG: hServicesListCtrl = GetDlgItem(hDlg, IDC_SERVICES_LIST); hServicesDialog = hDlg; dwStyle = (DWORD) SendMessage(hServicesListCtrl, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0); dwStyle = dwStyle | LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES; SendMessage(hServicesListCtrl, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle); SetWindowPos(hDlg, NULL, 10, 32, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER); // Initialize the application page's controls column.mask = LVCF_TEXT | LVCF_WIDTH; LoadString(hInst, IDS_SERVICES_COLUMN_SERVICE, szTemp, 256); column.pszText = szTemp; column.cx = 200; (void)ListView_InsertColumn(hServicesListCtrl, 0, &column); column.mask = LVCF_TEXT | LVCF_WIDTH; LoadString(hInst, IDS_SERVICES_COLUMN_REQ, szTemp, 256); column.pszText = szTemp; column.cx = 70; (void)ListView_InsertColumn(hServicesListCtrl, 1, &column); column.mask = LVCF_TEXT | LVCF_WIDTH; LoadString(hInst, IDS_SERVICES_COLUMN_VENDOR, szTemp, 256); column.pszText = szTemp; column.cx = 200; (void)ListView_InsertColumn(hServicesListCtrl, 2, &column); column.mask = LVCF_TEXT | LVCF_WIDTH; LoadString(hInst, IDS_SERVICES_COLUMN_STATUS, szTemp, 256); column.pszText = szTemp; column.cx = 70; (void)ListView_InsertColumn(hServicesListCtrl, 3, &column); GetServices(); return TRUE; } return 0; }
void Variable::SetValue(const DataValue& value) { WriteValue writeValue; writeValue.Attribute = AttributeID::VALUE; writeValue.Data = value; writeValue.Node = Id; std::vector<StatusCode> result = GetServices()->Attributes()->Write({writeValue}); if (result.size() != 1) { throw std::runtime_error("Failed to write data. Server returned wron nunber of status codes."); } CheckStatusCode(result[0]); }
std::vector<ReferenceDescription> Object::BrowseObjectsAndVariables(const NodeId& id) { // Id of the new node. BrowseDescription desc; desc.Direction = BrowseDirection::Forward; desc.IncludeSubtypes = true; desc.NodeClasses = NodeClass::Object | NodeClass::Variable | NodeClass::Method; desc.ReferenceTypeId = ObjectId::HierarchicalReferences; desc.NodeToBrowse = id; desc.ResultMask = BrowseResultMask::NodeClass | BrowseResultMask::TypeDefinition | BrowseResultMask::BrowseName | BrowseResultMask::DisplayName; // browse sub objects and variables. NodesQuery query; query.NodesToBrowse.push_back(desc); ViewServices::SharedPtr views = GetServices()->Views(); return views->Browse(query)[0].Referencies; //FIME: this method should return BrowseResults }
AddNodesItem Object::CreateVariableCopy(const NodeId& parentId, const ReferenceDescription& ref) { const NodeId& nodeId = ref.TargetNodeId; ReadParameters readParams; readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::DisplayName)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::Description)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::Value)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::DataType)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::ValueRank)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::ArrayDimensions)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::AccessLevel)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::UserAccessLevel)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::MinimumSamplingInterval)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::Historizing)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::WriteMask)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::UserWriteMask)); readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::BrowseName)); std::vector<DataValue> values = GetServices()->Attributes()->Read(readParams); VariableAttributes attrs; attrs.DisplayName = values[0].Value.As<LocalizedText>(); attrs.Description = values[1].Value.As<LocalizedText>(); attrs.Value = values[2].Value; attrs.Type = values[3].Value.As<NodeId>(); attrs.Rank = values[4].Value.As<int32_t>(); attrs.Dimensions = values[5].Value.As<std::vector<uint32_t>>(); attrs.AccessLevel = static_cast<VariableAccessLevel>(values[6].Value.As<uint8_t>()); attrs.UserAccessLevel = static_cast<VariableAccessLevel>(values[7].Value.As<uint8_t>()); attrs.MinimumSamplingInterval = values[8].Value.As<Duration>(); attrs.Historizing = values[9].Value.As<bool>(); attrs.WriteMask = values[10].Value.As<uint32_t>(); attrs.UserWriteMask = values[11].Value.As<uint32_t>(); AddNodesItem newNode; newNode.BrowseName = values[12].Value.As<QualifiedName>(); newNode.Class = NodeClass::Variable; newNode.ParentNodeId = parentId; newNode.ReferenceTypeId = ref.ReferenceTypeId; newNode.TypeDefinition = ref.TargetNodeTypeDefinition; newNode.Attributes = attrs; return newNode; }
std::map<NodeId, std::vector<ReferenceDescription>> Object::CopyObjectsAndVariables(const NodeId& targetNode, const std::vector<ReferenceDescription>& refs) { std::map<NodeId, std::vector<ReferenceDescription>> nextCopyData; for (const ReferenceDescription& ref : refs) { std::vector<AddNodesResult> result; std::vector<AddNodesItem> newNodeRequest; switch (ref.TargetNodeClass) { case NodeClass::Object: { if (ref.TargetNodeTypeDefinition !=ObjectId::Null) { InstantiateType(NodeId(), targetNode, ref.TargetNodeTypeDefinition, NodeClass::Object, ref.BrowseName, ref.DisplayName.Text); } else { newNodeRequest = {CreateObjectCopy(targetNode, ref)}; } break; } case NodeClass::Variable: { newNodeRequest = {CreateVariableCopy(targetNode, ref)}; break; } default: { continue; } } if (newNodeRequest.empty()) { continue; } result = GetServices()->NodeManagement()->AddNodes(newNodeRequest); std::vector<ReferenceDescription> newRefs = BrowseObjectsAndVariables(ref.TargetNodeId); nextCopyData.insert({result[0].AddedNodeId, newRefs}); } return nextCopyData; }
NodeId Object::InstantiateType(const NodeId& newNodeId, const NodeId& parentNode, const NodeId& typeId, NodeClass nodeClass, const QualifiedName& browseName, const std::string& displayName) { // Creating new node for object AddNodesItem newNodeRequest; newNodeRequest.BrowseName = browseName; newNodeRequest.RequestedNewNodeId = newNodeId; newNodeRequest.Class = nodeClass; newNodeRequest.ParentNodeId = parentNode; newNodeRequest.ReferenceTypeId = nodeClass == NodeClass::Object ? ObjectId::HasComponent : ObjectId::HasProperty; newNodeRequest.TypeDefinition = typeId; ObjectAttributes attrs; attrs.Description = LocalizedText(displayName); attrs.DisplayName = LocalizedText(displayName); newNodeRequest.Attributes = attrs; NodeManagementServices::SharedPtr nodes = GetServices()->NodeManagement(); std::vector<AddNodesResult> newObjectNode = nodes->AddNodes({newNodeRequest}); if (newObjectNode.size() != 1) { throw std::runtime_error("opcua_model| Server returned wrong number new nodes results."); } OpcUa::CheckStatusCode(newObjectNode[0].Status); std::map<NodeId, std::vector<ReferenceDescription>> nextRefs; nextRefs.insert({newObjectNode[0].AddedNodeId, BrowseObjectsAndVariables(typeId)}); while(!nextRefs.empty()) { std::map<NodeId, std::vector<ReferenceDescription>> newRefs; for (auto idRefs : nextRefs) { std::map<NodeId, std::vector<ReferenceDescription>> tmpRefs = CopyObjectsAndVariables(idRefs.first, idRefs.second); newRefs.insert(tmpRefs.begin(), tmpRefs.end()); } nextRefs = std::move(newRefs); } return newObjectNode[0].AddedNodeId; }
std::vector<Variable> Object::GetVariables() const { return Browse<Variable>(GetId(), NodeClass::Variable, GetServices()); }
ObjectType Object::GetType() const { return ObjectType(ObjectId::Null, GetServices()); }
Object Object::GetObject(const QualifiedName& name) const { return Object(ObjectId::Null, GetServices()); }
Object Object::GetObject(const RelativePath& name) const { return Object(ObjectId::Null, GetServices()); }
std::vector<Variable> Variable::Variables() const { return Browse<Variable>(GetID(), NODE_CLASS_VARIABLE, GetServices()); }
std::vector<Object> Object::GetObjects() const { return Browse<Object>(GetId(), NodeClass::Object, GetServices()); }
Variable Object::CreateVariable(const NodeId& newVariableId, const QualifiedName& browseName, const VariableType& type) { return Variable(GetServices()); }
INT_PTR CALLBACK ServicesPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); UNREFERENCED_PARAMETER(wParam); switch (message) { case WM_INITDIALOG: { hServicesPage = hDlg; hServicesListCtrl = GetDlgItem(hServicesPage, IDC_SERVICES_LIST); // // Correctly display message strings. // LPCWSTR szOSVendor = (bIsWindows ? IDS_MICROSOFT : IDS_REACTOS); size_t itemLength = 0; LPWSTR szItem = NULL, szNewItem = NULL; itemLength = GetWindowTextLength(GetDlgItem(hServicesPage, IDC_STATIC_SERVICES_WARNING)) + 1; szItem = (LPWSTR)MemAlloc(0, itemLength * sizeof(WCHAR)); GetDlgItemText(hServicesPage, IDC_STATIC_SERVICES_WARNING, szItem, (int)itemLength); szNewItem = FormatString(szItem, szOSVendor); SetDlgItemText(hServicesPage, IDC_STATIC_SERVICES_WARNING, szNewItem); MemFree(szNewItem); MemFree(szItem); itemLength = GetWindowTextLength(GetDlgItem(hServicesPage, IDC_CBX_SERVICES_MASK_PROPRIETARY_SVCS)) + 1; szItem = (LPWSTR)MemAlloc(0, itemLength * sizeof(WCHAR)); GetDlgItemText(hServicesPage, IDC_CBX_SERVICES_MASK_PROPRIETARY_SVCS, szItem, (int)itemLength); szNewItem = FormatString(szItem, szOSVendor); SetDlgItemText(hServicesPage, IDC_CBX_SERVICES_MASK_PROPRIETARY_SVCS, szNewItem); MemFree(szNewItem); MemFree(szItem); // // Initialize the styles. // DWORD dwStyle = ListView_GetExtendedListViewStyle(hServicesListCtrl); ListView_SetExtendedListViewStyle(hServicesListCtrl, dwStyle | LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES); SetWindowTheme(hServicesListCtrl, L"Explorer", NULL); // // Initialize the application page's controls. // LVCOLUMN column = {}; // First column : Service's name. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_SERVICE); column.cx = 150; ListView_InsertColumn(hServicesListCtrl, 0, &column); MemFree(column.pszText); // Second column : Whether the service is required or not. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_REQ); column.cx = 60; ListView_InsertColumn(hServicesListCtrl, 1, &column); MemFree(column.pszText); // Third column : Service's vendor. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_VENDOR); column.cx = 150; ListView_InsertColumn(hServicesListCtrl, 2, &column); MemFree(column.pszText); // Fourth column : Service's status. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_STATUS); column.cx = 60; ListView_InsertColumn(hServicesListCtrl, 3, &column); MemFree(column.pszText); // Fifth column : Service's disabled date. column.mask = LVCF_TEXT | LVCF_WIDTH; column.pszText = LoadResourceString(hInst, IDS_SERVICES_COLUMN_DATEDISABLED); column.cx = 120; ListView_InsertColumn(hServicesListCtrl, 4, &column); MemFree(column.pszText); // // Populate and sort the list. // GetServices(); ListView_Sort(hServicesListCtrl, 0); Update_Btn_States(hDlg); // Select the first item. ListView_SetItemState(hServicesListCtrl, 0, LVIS_SELECTED, LVIS_SELECTED); return TRUE; } case WM_DESTROY: { ClearServicesList(); userModificationsList.RemoveAll(); return 0; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_BTN_SERVICES_ACTIVATE: { BOOL bAreThereModifs = FALSE; int index = -1; // From the beginning. while ((index = ListView_GetNextItem(hServicesListCtrl, index, LVNI_ALL)) != -1) { bAreThereModifs = ValidateItem(index, TRUE, FALSE) || bAreThereModifs; // The order is verrrrrry important !!!! } if (bAreThereModifs) { Update_Btn_States(hDlg); PropSheet_Changed(GetParent(hServicesPage), hServicesPage); } return TRUE; } case IDC_BTN_SERVICES_DEACTIVATE: { BOOL bAreThereModifs = FALSE; int index = -1; // From the beginning. while ((index = ListView_GetNextItem(hServicesListCtrl, index, LVNI_ALL)) != -1) { bAreThereModifs = ValidateItem(index, FALSE, FALSE) || bAreThereModifs; // The order is verrrrrry important !!!! } if (bAreThereModifs) { Update_Btn_States(hDlg); PropSheet_Changed(GetParent(hServicesPage), hServicesPage); } return TRUE; } case IDC_CBX_SERVICES_MASK_PROPRIETARY_SVCS: { bMaskProprietarySvcs = !bMaskProprietarySvcs; GetServices(bMaskProprietarySvcs); Update_Btn_States(hDlg); return TRUE; } default: return FALSE; } return FALSE; } case UM_CHECKSTATECHANGE: { BOOL bNewCheckState = !!((ListView_GetCheckState(hServicesListCtrl, int(lParam)) + 1) % 2); if (ValidateItem(/*reinterpret_cast<int>*/ int(lParam), bNewCheckState, !HideEssentialServiceWarning())) { Update_Btn_States(hDlg); PropSheet_Changed(GetParent(hServicesPage), hServicesPage); } return TRUE; } case WM_NOTIFY: { if (reinterpret_cast<LPNMHDR>(lParam)->hwndFrom == hServicesListCtrl) { switch (reinterpret_cast<LPNMHDR>(lParam)->code) { case NM_CLICK: case NM_RCLICK: { DWORD dwpos = GetMessagePos(); LVHITTESTINFO ht = {}; ht.pt.x = GET_X_LPARAM(dwpos); ht.pt.y = GET_Y_LPARAM(dwpos); MapWindowPoints(HWND_DESKTOP /*NULL*/, hServicesListCtrl, &ht.pt, 1); /* * We use ListView_SubItemHitTest(...) and not ListView_HitTest(...) * because ListView_HitTest(...) returns bad flags when one clicks * on a sub-item different from 0. The flags then contain LVHT_ONITEMSTATEICON * which must not be obviously present in this case. */ ListView_SubItemHitTest(hServicesListCtrl, &ht); if (LVHT_ONITEMSTATEICON & ht.flags) { PostMessage(hDlg, UM_CHECKSTATECHANGE, 0, (LPARAM)ht.iItem); // Disable default behaviour. Needed for the UM_CHECKSTATECHANGE // custom notification to work as expected. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE); } return TRUE; } case NM_DBLCLK: case NM_RDBLCLK: { // We deactivate double-clicks. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE); return TRUE; } case LVN_KEYDOWN: { if (reinterpret_cast<LPNMLVKEYDOWN>(lParam)->wVKey == VK_SPACE) { int iItem = ListView_GetSelectionMark(hServicesListCtrl); PostMessage(hDlg, UM_CHECKSTATECHANGE, 0, (LPARAM)iItem); // Disable default behaviour. Needed for the UM_CHECKSTATECHANGE // custom notification to work as expected. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE); } return TRUE; } case LVN_COLUMNCLICK: { int iSortingColumn = reinterpret_cast<LPNMLISTVIEW>(lParam)->iSubItem; ListView_SortEx(hServicesListCtrl, iSortingColumn, iSortedColumn); iSortedColumn = iSortingColumn; return TRUE; } } } else { switch (reinterpret_cast<LPNMHDR>(lParam)->code) { case PSN_APPLY: { // Try to apply the modifications to the system. MessageBox(NULL, _T("In Services page: PSN_APPLY"), _T("Info"), MB_ICONINFORMATION); /* // // Move this away... // int iRetVal = MessageBox(NULL, _T("Would you really want to modify the configuration of your system ?"), _T("Warning"), MB_ICONWARNING | MB_YESNOCANCEL); if (iRetVal == IDYES /\* modifications are OK *\/) SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_NOERROR); else if (iRetVal == IDNO /\* modifications are not OK *\/) SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_NOERROR); else // if (iRetVal == IDCANCEL) // There was an error... SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_INVALID); */ // // We modify the services which are stored in the user modification list. // // 1- Open the Service Control Manager for modifications. SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hSCManager != NULL) { LPCWSTR svcName; for (POSITION it = userModificationsList.GetHeadPosition(); it; userModificationsList.GetNext(it)) { svcName = userModificationsList.GetAt(it); // 2- Retrieve a handle to the service. SC_HANDLE hService = OpenServiceW(hSCManager, svcName, SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG); if (hService == NULL) { // TODO : Show a message box. continue; } DWORD dwBytesNeeded = 0; QueryServiceConfigW(hService, NULL, 0, &dwBytesNeeded); // if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) LPQUERY_SERVICE_CONFIG lpServiceConfig = (LPQUERY_SERVICE_CONFIG)MemAlloc(0, dwBytesNeeded); if (!lpServiceConfig) { CloseServiceHandle(hService); continue; // TODO ? Show a message box... } QueryServiceConfigW(hService, lpServiceConfig, dwBytesNeeded, &dwBytesNeeded); if (lpServiceConfig->dwStartType == SERVICE_DISABLED) // We have a disabled service which is becoming to be enabled. { // 3a- Retrive the properties of the disabled service from the registry. RegistryDisabledServiceItemParams params = {}; QUERY_REGISTRY_KEYS_TABLE KeysQueryTable[2] = {}; KeysQueryTable[0].QueryRoutine = GetRegistryKeyedDisabledServicesQueryRoutine; KeysQueryTable[0].EntryContext = ¶ms; RegQueryRegistryKeys(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", KeysQueryTable, (PVOID)svcName); if (bIsWindows && bIsPreVistaOSVersion && !params.bIsPresent) { QUERY_REGISTRY_VALUES_TABLE ValuesQueryTable[2] = {}; ValuesQueryTable[0].QueryRoutine = GetRegistryValuedDisabledServicesQueryRoutine; ValuesQueryTable[0].EntryContext = ¶ms; RegQueryRegistryValues(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", ValuesQueryTable, (PVOID)svcName); } if (params.bIsPresent) { // 4a- Modify the service. ChangeServiceConfigW(hService, SERVICE_NO_CHANGE, params.dwStartType, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); // 5a- Remove the registry entry of the service. if (params.bIsKeyed) { CAtlStringW serviceRegKey(L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services\\"); serviceRegKey += svcName; RegDeleteKeyW(HKEY_LOCAL_MACHINE, serviceRegKey); /***** HACK for Windows < Vista (e.g. 2000, Xp, 2003...) *****/ // // Delete also the valued-entry of the service. // if (bIsWindows && bIsPreVistaOSVersion) { HKEY hSubKey = NULL; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", 0, KEY_SET_VALUE /*KEY_READ*/, &hSubKey) == ERROR_SUCCESS) { RegDeleteValue(hSubKey, svcName); RegCloseKey(hSubKey); } } /*************************************************************/ } else { HKEY hSubKey = NULL; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", 0, KEY_SET_VALUE /*KEY_READ*/, &hSubKey) == ERROR_SUCCESS) { RegDeleteValue(hSubKey, svcName); RegCloseKey(hSubKey); } } ////////// HACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACK /////////// // userModificationsList.RemoveAt(it); } else { // Ohoh !! We have a very big problem. MessageBox(NULL, _T("WTF ??"), _T("FATAL ERROR !!!!"), MB_ICONERROR); } } else // We have an enabled service which is becoming to be disabled. { // 3b- Retrieve the local time of disabling. SYSTEMTIME disableDate = {}; GetLocalTime(&disableDate); // 4b- Modify the service. ChangeServiceConfigW(hService, SERVICE_NO_CHANGE, SERVICE_DISABLED, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); // 5b- Register the service into the registry. CAtlStringW serviceRegKey(L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services\\"); serviceRegKey += svcName; HKEY hSubKey = NULL; if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, serviceRegKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hSubKey, NULL) == ERROR_SUCCESS) { RegSetDWORDValue(hSubKey, NULL, svcName, FALSE, lpServiceConfig->dwStartType); #if 1 // DisableDate RegSetDWORDValue(hSubKey, NULL, L"DAY" , FALSE, disableDate.wDay ); RegSetDWORDValue(hSubKey, NULL, L"HOUR" , FALSE, disableDate.wHour ); RegSetDWORDValue(hSubKey, NULL, L"MINUTE", FALSE, disableDate.wMinute); RegSetDWORDValue(hSubKey, NULL, L"MONTH" , FALSE, disableDate.wMonth ); RegSetDWORDValue(hSubKey, NULL, L"SECOND", FALSE, disableDate.wSecond); RegSetDWORDValue(hSubKey, NULL, L"YEAR" , FALSE, disableDate.wYear ); #endif RegCloseKey(hSubKey); } /***** HACK for Windows < Vista (e.g. 2000, Xp, 2003...) *****/ // // Save also a valued-entry for the service. // if (bIsWindows && bIsPreVistaOSVersion) { RegSetDWORDValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", svcName, TRUE, lpServiceConfig->dwStartType); } /*************************************************************/ ////////// HACKHACKHACKHACKHACKHACKHACKHACKHACKHACKHACK /////////// // userModificationsList.RemoveAt(it); } MemFree(lpServiceConfig); CloseServiceHandle(hService); } //////////// HACK HACK !!!! //////////// userModificationsList.RemoveAll(); //////////////////////////////////////// CloseServiceHandle(hSCManager); //// PropSheet_UnChanged(GetParent(hServicesPage), hServicesPage); //// PropSheet_CancelToClose(GetParent(hDlg)); /* Modifications are OK */ SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_NOERROR); } else { MessageBox(hDlg, _T("Impossible to open the SC manager..."), _T("Error"), MB_ICONERROR); // There was an error... SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, PSNRET_INVALID); } GetServices(bMaskProprietarySvcs); Update_Btn_States(hDlg); return TRUE; } case PSN_HELP: { MessageBox(hServicesPage, _T("Help not implemented yet!"), _T("Help"), MB_ICONINFORMATION | MB_OK); return TRUE; } case PSN_KILLACTIVE: // Is going to lose activation. { // Changes are always valid of course. SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, FALSE); return TRUE; } case PSN_QUERYCANCEL: { // RefreshStartupList(); // Allows cancellation. SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, FALSE); return TRUE; } case PSN_QUERYINITIALFOCUS: { // Give the focus on and select the first item. ListView_SetItemState(hServicesListCtrl, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, (LONG_PTR)hServicesListCtrl); return TRUE; } // // DO NOT TOUCH THESE NEXT MESSAGES, THEY ARE OK LIKE THIS... // case PSN_RESET: // Perform final cleaning, called before WM_DESTROY. return TRUE; case PSN_SETACTIVE: // Is going to gain activation. { SetWindowLongPtr(hServicesPage, DWLP_MSGRESULT, 0); return TRUE; } default: break; } } } default: return FALSE; } return FALSE; }