Beispiel #1
0
STDMETHODIMP LightOPCGroup::GetState (DWORD *pUpdateRate, BOOL *pActive, LPWSTR *ppName,
		                  LONG *pTimeBias, FLOAT *pPercentDeadband, DWORD *pLCID,
		                  OPCHANDLE * phClientGroup, OPCHANDLE * phServerGroup)
{
 HRESULT hr = S_OK;

 LO_CHECK_STATEz1("GetState", ppName);

 if (!ppName) { hr = E_INVALIDARG; goto Return; }

 UL_TRACE((LOG_GRH("LightOPCGroup::GetState()")));

 lock_read();
     if (phClientGroup) *phClientGroup = ClientHandle;
     if (phServerGroup) *phServerGroup = ServerHandle;
     if (pUpdateRate) *pUpdateRate = UpdateRate;
     if (pActive) *pActive = Active;
     if (pPercentDeadband) *pPercentDeadband = Deadband;
     if (pLCID) *pLCID = grLCID;
     if (pTimeBias) *pTimeBias = TimeBias;
     if (ppName && !(*ppName = loComWstrdup(name))) hr = E_OUTOFMEMORY;
 unlock();

Return:
 if (S_OK != hr) UL_INFO((LOG_GRH("GetGroupState() =%s"), loStrError(hr)));
 else UL_NOTICE((LOG_GRH("GetGroupState(%ls) = Ok"), loWnul(ppName? *ppName: 0)));

 LO_FINISH();
 return hr;
}
Beispiel #2
0
STDMETHODIMP LightOPCServer::GetGroupByName(LPCWSTR szGroupName, REFIID riid, LPUNKNOWN *ppUnk)
{
 HRESULT hr = S_OK;
 LightOPCGroup *grp;

 LO_CHECK_STATEz1("GetGroupByName", ppUnk);
 UL_TRACE((LOG_SR("GetGroupByName(%ls)"), loWnul(szGroupName)));
 if (!ppUnk) hr = E_INVALIDARG;
 else
   {
    if (!szGroupName) hr = E_INVALIDARG;
    else
      {
       lock_read();
          hr = loOPC_E_NOTFOUND;
	  if (grp = by_name(szGroupName))
	    hr = grp->QueryInterface(riid, (LPVOID*)ppUnk);
       unlock();
      }
   }

 if (S_OK != hr) UL_INFO((LOG_SR("GetGroupByName(%ls) =%s"),
               loWnul(szGroupName), loStrError(hr)));
 else UL_NOTICE((LOG_SR("GetGroupByName(%ls) =%u /%p"),
			szGroupName, ((LightOPCGroup*)grp)->ServerHandle, *ppUnk));
 LO_FINISH();
 return hr;
}
void loSearchIID(IUnknown *punk)
{
 DWORD indx;
 HKEY key;
 char buf[256], *tbuf;

 UL_TRACE((LOGID, "Iface: %p", punk));

 if (ERROR_SUCCESS != RegOpenKey(HKEY_CLASSES_ROOT, "Interface", &key))
   {
    UL_ERROR((LOGID, "%!L RegOpenKey(Interface)"));
    return;
   }
 strcpy(buf, "Interface\\");
 tbuf = buf + strlen(buf);
 for(indx = 0; ERROR_SUCCESS == RegEnumKey(
               key, indx, tbuf, buf + sizeof(buf) - tbuf); indx++)
   {
    GUID iid;
    HRESULT hr;
    IUnknown *qi;
    LONG cb;
    char name[256]; name[0] = 0;
    cb = sizeof(name);
    RegQueryValue(key, tbuf, name, &cb);
    StrToIID(&iid, tbuf);
    if (S_OK == (hr = punk->QueryInterface(iid, (LPVOID*)&qi)))
      {
       UL_TRACE((LOGID, "Ok %s %p", name, qi));
       qi->Release();
      }
/*    else if (hr != E_NOINTERFACE)
      {
       UL_DEBUG((LOGID, "%!l %s -> %s", hr, name, tbuf));
      }    */
   }
 RegCloseKey(key);
}
Beispiel #4
0
STDMETHODIMP LightOPCGroup::SetState(DWORD *pRequestedUpdateRate, DWORD *pRevisedUpdateRate,
		                  BOOL *pActive, LONG *pTimeBias, FLOAT *pPercentDeadband,
		                  DWORD *pLCID, OPCHANDLE *phClientGroup)
{
 HRESULT hr = S_OK;

 LO_CHECK_STATEz0("SetState");
 UL_TRACE((LOG_GRH("LightOPCGroup::SetState()")));

 if (pLCID && owner->se->driver.ldCheckLocale &&
              owner->se->driver.ldCheckLocale(&owner->ctxt.cactx, *pLCID))
   pLCID = 0; /* ignore on errors */
 lock_write();
    if (pRequestedUpdateRate)
      {
//	  if (!pRevisedUpdateRate) hr = E_INVALIDARG;
       DWORD revised_rate = loReviseUpdateRate(owner->se, *pRequestedUpdateRate);
       if (UpdateRate > revised_rate && (!pActive || *pActive)
         /* && Active && 0 != (advise_present & advise_enabled)*/)
         UpdateRate = revised_rate, actuate_async(0);
       else UpdateRate = revised_rate;
       if (UpdateRate != *pRequestedUpdateRate) hr = OPC_S_UNSUPPORTEDRATE;
      }
    if (pRevisedUpdateRate) *pRevisedUpdateRate = UpdateRate;
    if (pActive) set_active(*pActive);
    if (pTimeBias) TimeBias = *pTimeBias;
    if (pPercentDeadband)
      if (lo_IsNANf(*pPercentDeadband) ||
          *pPercentDeadband < 0. ||
          *pPercentDeadband > 100.) hr = E_INVALIDARG;
      else Deadband = *pPercentDeadband;
    if (pLCID) grLCID = *pLCID;
    if (phClientGroup) ClientHandle = *phClientGroup;
 unlock();

 if (!FAILED(hr)) UL_NOTICE((LOG_GR("SetGroupState(%u) =(%umS (%umS) %g%%)Ok"),
                  ServerHandle, (unsigned)UpdateRate,
                  (unsigned)(pRequestedUpdateRate? *pRequestedUpdateRate: 0),
                  Deadband));
 else UL_INFO((LOG_GR("SetGroupState(%u) =%s"), ServerHandle, loStrError(hr)));

 LO_FINISH();
 return hr;
}
Beispiel #5
0
STDMETHODIMP LightOPCServer::RemoveGroup(OPCHANDLE groupHandleID, BOOL bForce)
{
 HRESULT hr = loOPC_E_INVALIDHANDLE;

 LO_CHECK_STATEz0("RemoveGroup");
 UL_TRACE((LOG_SR("RemoveGroup(%u %s)"), groupHandleID, bForce? "FORCE": ""));

 if (groupHandleID)
   {
#if LO_USE_BOTHMODEL
    if (ldFlags & loDf_BOTHMODEL)
      {
       loRequest *rq = lo_req_alloc(0, 0);
       UL_DEBUG((LOG_SR("RemoveGroup() going to async")));
       if (!rq) hr = E_OUTOFMEMORY;
       else
         {
          rq->operation = loRQ_SYNC | loRQ_OP_REMOVE_GROUP |
                             (bForce? loRQ_OF_REMOVE_FORCE: 0);
          rq->group_key = groupHandleID;
          rq->serv_key = serv_key;

          if (rq = lo_req_put_sync(&q_req, &q_ret, rq))
            {
             hr = rq->upl.master_err;
             lo_req_free(rq);
            }
          else hr = E_FAIL;
         }
      }
    else
#endif
        hr = internalRemoveGroup(groupHandleID, bForce);
   }

 if (S_OK != hr) UL_INFO((LOG_SR("RemoveGroup(%u %s) =%s"),
                              groupHandleID, bForce? "FORCE": "", loStrError(hr)));
 else UL_NOTICE((LOG_SR("RemoveGroup(%u %s) =Ok"), groupHandleID, bForce? "FORCE": ""));

 LO_FINISH();
 return hr;
}
Beispiel #6
0
int loServiceDestroy(loService *se)
{
    UL_TRACE((LOGID, "loServiceDestroy(%p)...", se));

    if (!loIS_VALID(se)) return EBADF;
    if ((se->initphase & (ifLKLIST|ifLKSEC)) == (ifLKLIST|ifLKSEC))
    {
        lw_mutex_lock(&se->lkList);
        if (se->shutdown)
        {
            lw_mutex_unlock(&se->lkList);
            UL_ERROR((LOGID, "loServiceDestroy(%p) shutdown started again", se));
            return EBADF;
        }
        if (se->servlist)
        {
            LightOPCServer *los = (LightOPCServer*)se->servlist;
            se->shutdown = 1;
            while(los)
            {
                los->set_state(loOP_SHUTDOWN|loOP_STOP|loOP_DISCONNECT, 0, 0);
                los = los->serv_next;
            }
            lw_mutex_unlock(&se->lkList);
            UL_NOTICE((LOGID, "loServiceDestroy(%p) shutdown started", se));
            return EBUSY;
        }
        se->shutdown = -1;
        lw_mutex_unlock(&se->lkList);
#if 0
        loThrControl_stop(&se->update_pipe);
#endif
        lw_condb_broadcast_continious(&se->lkTridWait, &se->update_pipe.lk);
    }
    return loInternalServiceDestroy(se);
}
Beispiel #7
0
STDMETHODIMP LightOPCGroup::SetName(LPCWSTR szName)
{
 HRESULT hr = S_OK;

 LO_CHECK_STATEz0("SetName");

 UL_TRACE((LOG_GRH("LightOPCGroup::SetName()")));
 if (!szName) hr = E_INVALIDARG;
 else
   {
    LightOPCGroup *grp;
    lock_write();
       grp = owner->by_name(szName);
       if (!grp) hr = set_name(szName);
       else if (grp != this) hr = OPC_E_DUPLICATENAME;
    unlock();
   }
 if (S_OK != hr) UL_INFO((LOG_GRH("SetGroupName(%ls) =%s"),
                              loWnul(szName), loStrError(hr)));
 else UL_NOTICE((LOG_GRH("SetGroupName(%ls)"), szName));

 LO_FINISH();
 return hr;
}
int loServerRegister(const GUID *CLSID_Svr, const char *ProgID,
                     const char *Name, const char *exPath,
                     const char *Model /* 0=exe, ""=STA dll, "Both", "Free" ...*/)
{
 HKEY hKey;
 HKEY hKeyAux;
 char sStr[260];
 char sIID [40];
 const char *srvtype = "InprocServer32";
 LONG ec = ERROR_INVALID_PARAMETER;

 if (!ProgID /*|| !exPath*/) goto SetErr;
 if (exPath && !*exPath) exPath = NULL;
 UL_TRACE((LOGID, "loServerRegister(%s)", ProgID));

 if (0 == Model) srvtype = "LocalServer32";
/*   {
    char *ext;
    if (0 > extype ||
        (ext = strrchr(exPath, '.')) &&
        !stricmp(ext, ".exe")) srvtype = "LocalServer32";
   }*/

 IIDtoStr (sIID, CLSID_Svr);

 if (ERROR_SUCCESS != (ec = RegCreateKey(HKEY_CLASSES_ROOT, ProgID, &hKey)))
   goto SetErr;
   
  if (Name) RegSetValue(hKey, NULL, REG_SZ, Name, strlen(Name)+1);
  if (ERROR_SUCCESS != (ec = RegCreateKey(hKey, "CLSID", &hKeyAux)))
    goto Fail;
  ec = RegSetValue(hKeyAux, NULL, REG_SZ, sIID, strlen(sIID)+1);
  RegCloseKey(hKeyAux);
  if (ERROR_SUCCESS != ec) goto Fail;

  if (ERROR_SUCCESS != (ec = RegCreateKey(hKey, "OPC", &hKeyAux)))
    goto Fail;
{
  HKEY vendor;
/*        RegSetValue (hKeyAux, NULL, REG_SZ, sIID, strlen(sIID)+1); */
/* Should "vendor" be a subkey or a named value? */
  if (ERROR_SUCCESS == RegCreateKey(hKeyAux, "Vendor", &vendor))
    {
     RegSetValue(vendor, NULL, REG_SZ, "ConnectSpot", sizeof("ConnectSpot"));
     RegCloseKey(vendor);
    }
  RegCloseKey(hKeyAux);
}
  RegCloseKey(hKey);

 sprintf (sStr, "AppID\\%s", sIID);
 if (ERROR_SUCCESS != (ec = RegCreateKey(HKEY_CLASSES_ROOT, sStr, &hKey)))
   goto UnReg;
 if (Name) RegSetValue(hKey, NULL, REG_SZ, Name, strlen(Name)+1);
/* DllSurrogate=""
   RunAs="Interactive User"
   RemoteServerName= */
 RegCloseKey(hKey);

 sprintf (sStr, "CLSID\\%s", sIID);
 if (ERROR_SUCCESS != (ec = RegCreateKey(HKEY_CLASSES_ROOT, sStr, &hKey)))
   goto UnReg;
 if (Name) RegSetValue(hKey, NULL, REG_SZ, Name, strlen(Name)+1);
 if (exPath)
   {
    if (ERROR_SUCCESS != (ec = RegCreateKey(hKey, srvtype, &hKeyAux)))
      goto Fail;
    ec = RegSetValue(hKeyAux, NULL, REG_SZ, exPath, strlen(exPath)+1);
    if (Model && *Model) /* dll */
      RegSetValueEx(hKeyAux, "ThreadingModel", 0, REG_SZ, 
                    (const BYTE*)Model, strlen(Model)+1);
    RegCloseKey(hKeyAux);
    if (ERROR_SUCCESS != ec) goto Fail;
   }
  // The NAIL for DCOMcnfg !!!
  //       RegSetValueEx(hKeyAux, NULL, 0, REG_EXPAND_SZ, exPath, strlen(exPath)+1);
 RegSetValueEx(hKey, "AppID", 0, REG_SZ, (const BYTE*)sIID, strlen(sIID)+1);
  //    RegSetValue(hKey, "AppID", REG_SZ, sIID, strlen(sIID)+1);

 if (ERROR_SUCCESS != (ec = RegCreateKey(hKey, "ProgID", &hKeyAux)))
   goto Fail;
 ec = RegSetValue(hKeyAux, NULL, REG_SZ, ProgID, strlen(ProgID)+1);
 RegCloseKey(hKeyAux);
 if (ERROR_SUCCESS != ec) goto Fail;

 if (FAILED(manageOPCDAcat(CLSID_Svr, 0)))
   {
    IIDtoStr(sIID, &CATID_OPCDAServer10);
    sprintf (sStr, "Implemented Categories\\%s", sIID);
    if (ERROR_SUCCESS != (ec = RegCreateKey(hKey, sStr, &hKeyAux)))
      goto Fail;
    RegCloseKey(hKeyAux);
    IIDtoStr (sIID, &CATID_OPCDAServer20);
    sprintf (sStr, "Implemented Categories\\%s", sIID);
    if (ERROR_SUCCESS != (ec = RegCreateKey(hKey, sStr, &hKeyAux)))
      goto Fail;
    RegCloseKey(hKeyAux);
   }
 RegCloseKey(hKey);

 return 0;

Fail:
 RegCloseKey(hKey);
UnReg:
 loServerUnregister(CLSID_Svr, Name);
SetErr:
 SetLastError(ec);
 UL_ERROR((LOGID, "%!l loServerRegister(%s) FAILED", 
          ec, ProgID? ProgID: "<null>"));
 return -1;
}
int loServerUnregister(const GUID *CLSID_Svr, const char *ProgID)
{
	char sStr[256];
	char sIID [40];
    int offs;
    LONG errs = ERROR_INVALID_PARAMETER, ec = 0;
	IIDtoStr (sIID, CLSID_Svr);

    if (!ProgID || !*ProgID) goto SetErr;

    UL_TRACE((LOGID, "loUnRegisterServer(%s)", ProgID));

    manageOPCDAcat(CLSID_Svr, -1);

	offs = sprintf(sStr, "%s\\", ProgID);
    strcpy(sStr + offs, "CurrentVersion");
	RegDeleteKey (HKEY_CLASSES_ROOT, sStr);
	strcpy(sStr + offs, "OPC\\Vendor");
	RegDeleteKey (HKEY_CLASSES_ROOT, sStr);

	strcpy(sStr + offs, "OPC");
	RegDeleteKey (HKEY_CLASSES_ROOT, sStr);
	strcpy(sStr + offs, "CLSID");
	errs = RegDeleteKey (HKEY_CLASSES_ROOT, sStr);
	if (ERROR_SUCCESS != (ec = RegDeleteKey (HKEY_CLASSES_ROOT, ProgID)))
      {
       if (ERROR_SUCCESS == errs) errs = ec;
       UL_NOTICE((LOGID, "loUnRegisterServer(%s) can't remove HKCR:%s", ProgID, ProgID));
      }

	offs = sprintf(sStr, "AppID\\%s\\", sIID);
	strcpy(sStr + offs, "LocalService");
	RegDeleteKey (HKEY_CLASSES_ROOT, sStr);
	strcpy(sStr + offs, "ServiceParameters");
	RegDeleteKey (HKEY_CLASSES_ROOT, sStr);
    sStr[offs - 1] = 0;
    if (ERROR_SUCCESS != (ec = RegDeleteKey (HKEY_CLASSES_ROOT, sStr)))
      {
       if (ERROR_SUCCESS == errs) errs = ec;
       UL_NOTICE((LOGID, "loUnRegisterServer(%s) can't remove %s", ProgID, sStr));
      }

	offs = sprintf(sStr, "CLSID\\%s\\", sIID);

    IIDtoStr(sIID, &CATID_OPCDAServer10);
	sprintf(sStr + offs, "Implemented Categories\\%s", sIID);
	RegDeleteKey (HKEY_CLASSES_ROOT, sStr);
    IIDtoStr(sIID, &CATID_OPCDAServer20);
	sprintf(sStr + offs, "Implemented Categories\\%s", sIID);
	RegDeleteKey (HKEY_CLASSES_ROOT, sStr);
	strcpy(sStr + offs, "Implemented Categories");
	RegDeleteKey (HKEY_CLASSES_ROOT, sStr);

	strcpy(sStr + offs, "InprocServer32\\ThreadingModel");
	RegDeleteKey (HKEY_CLASSES_ROOT, sStr);
	strcpy(sStr + offs, "InprocServer32");
	RegDeleteKey (HKEY_CLASSES_ROOT, sStr);
	strcpy(sStr + offs, "LocalServer32");
	RegDeleteKey (HKEY_CLASSES_ROOT, sStr);
	strcpy(sStr + offs, "InprocHandler32");
	RegDeleteKey (HKEY_CLASSES_ROOT, sStr);
	strcpy(sStr + offs, "ProgID");
	RegDeleteKey (HKEY_CLASSES_ROOT, sStr);
	strcpy(sStr + offs, "AppID");
	RegDeleteKey (HKEY_CLASSES_ROOT, sStr);
    sStr[offs - 1] = 0;
    if (ERROR_SUCCESS != (ec = RegDeleteKey (HKEY_CLASSES_ROOT, sStr)))
      {
       if (ERROR_SUCCESS == errs) errs = ec;
       UL_NOTICE((LOGID, "loUnRegisterServer(%s) can't remove %s", ProgID, sStr));
      }

SetErr:
    if (ERROR_SUCCESS != errs) 
      {
        SetLastError(errs);
        UL_ERROR((LOGID, "%!l loServerUnRegister(%s) FAILED", 
          errs, ProgID? ProgID: "<null>"));
        return -1;
      }
    return 0;
}
Beispiel #10
0
STDMETHODIMP LightOPCGroup::Write(DWORD dwCount, OPCHANDLE *phServer, VARIANT *pItemValues,
		                  DWORD dwTransactionID, DWORD *pdwCancelID, HRESULT **ppErrors)
{
 HRESULT hr = S_FALSE;
 HRESULT *errs = 0;
 loRequest *rq = 0;
 unsigned items_ok = 0;

 LO_CHECK_STATEz1("AsyncIO2:Write", ppErrors);

 UL_TRACE((LOG_GRH("AsyncIO2:Write(%u)..."), dwCount));

 if (!phServer || !dwCount || !pdwCancelID || !pItemValues)
   { hr = E_INVALIDARG; goto Return; }
 *pdwCancelID = 0;
 if (owner->q_req.metric_overload) { hr = CONNECT_E_ADVISELIMIT; goto Return; }

 errs = (HRESULT*)loComAlloc(dwCount * sizeof(HRESULT));
 rq = lo_req_alloc(dwCount, loUPL_AsyncWrite);
 if (!rq || !errs) { hr = E_OUTOFMEMORY; goto Return; }
 loTagPair_init(rq->upl.tagpair, dwCount);
 rq->operation = loRQ_OP_WRITE | loRQ_CONN_DATABACK | loRQ_DEVICE;
 rq->group_key = ServerHandle;
 rq->serv_key = owner->serv_key;
 rq->upl.transaction_id = dwTransactionID;
 rq->upl.rctx = owner->ctxt;

 lock_read();
 rq->upl.rctx.cta.vc_lcid = grLCID;

 if (owner->access_mode & loAM_RDONLY_OP)
   {
    unsigned ii;
    for(ii = 0; ii < dwCount; ii++) errs[ii] = OPC_E_BADRIGHTS;
    goto Unlock;
   }

 if (0 == (advise_present & loRQ_CONN_DATABACK)/*conn_databack*/)
   hr = CONNECT_E_NOCONNECTION;
 else
   {
    unsigned ii;
    loTagPair *tpl = rq->upl.tagpair;
//    HRESULT *errors = rq->upl.errors;
    LightOPCItem *it;
    loTagEntry *tags = owner->se->tags;

    for(ii = 0; ii < dwCount; ii++, pItemValues++)
      if (!(it = by_index(phServer[ii]))) errs[ii] = OPC_E_INVALIDHANDLE;
      else
        {
         loTagEntry *te = &tags[it->tid];

#if 0 != LO_CHECK_RIGHTS
         if (!(OPC_WRITEABLE & te->attr.taRights)) errs[ii] = OPC_E_BADRIGHTS;
         else
#endif
              if (VT_EMPTY == V_VT(pItemValues) || /*) *errors = OPC_E_BADTYPE;
         else if (*/S_OK == (errs[ii] =
                       VariantCopy(&rq->upl.variant[ii], pItemValues)))
           {
            tpl->tpTi = te->attr.taTi;
            tpl->tpRt = te->attr.taRt;
            tpl->tpAP = it->AcPath;
            tpl++;
            rq->upl.opchandle[items_ok++] = it->hClient;
            errs[ii] = S_OK;
           }
        }/* end of for */
   }
Unlock:
 unlock();

 if (items_ok)
   {
    rq->upl.used = items_ok;
    rq->upl.master_err = hr = items_ok == dwCount? S_OK: S_FALSE;
    if (0 == (*pdwCancelID = lo_req_put_async(&owner->q_req, rq)))
      hr = CONNECT_E_ADVISELIMIT;
    rq = 0;
   }

Return:
 if (rq) lo_req_free(rq);

 if (SUCCEEDED(hr))
   {
    if (ppErrors) *ppErrors = errs, errs = 0;
    UL_NOTICE((LOG_GRH("AsyncIO2:Write(%u) = %u -> %x Ok"),
                       dwCount, items_ok, *pdwCancelID));
   }
 else
   {
    UL_INFO((LOG_GRH("AsyncIO2:Write(%u) = %u /%s"),
               dwCount, items_ok, loStrError(hr)));
   }
 if (errs) loComFree(errs);

 LO_FINISH();
 return hr;
}
Beispiel #11
0
HRESULT LightOPCServer::internalAddGroup(
        LightOPCGroup *grp,
        LPCWSTR szName,
        BOOL bActive,
        DWORD UpdateRate,
        OPCHANDLE hClientGroup,
        LONG *pTimeBias,
        FLOAT *pPercentDeadband,
        DWORD dwLCID,
        OPCHANDLE *phServerGroup,
        REFIID riid,
        LPUNKNOWN *ppUnk
        )
{
 HRESULT hr = S_OK;
 unsigned servindex = 0;
 OPCHANDLE servhandle = 0;
 loWchar tname[loUNIQUE_LEN];

 if (phServerGroup) *phServerGroup = 0;
 if (!ppUnk) { hr = E_INVALIDARG; goto Exit; }
 *ppUnk = 0;

/*    if (!grp && !(grp = new LightOPCGroup()) ||
     grp->sstate != loST_READY) { hr = E_OUTOFMEMORY; goto Exit; }*/
/*  need assign all group atributes */
 grp->ClientHandle = hClientGroup;
 grp->UpdateRate = UpdateRate;
 grp->Active = bActive != 0;
 grp->Deadband = .0f;
 if (pPercentDeadband)
   {
    if (lo_IsNANf(*pPercentDeadband) ||
        *pPercentDeadband < 0. ||
        *pPercentDeadband > 100.) { hr = E_INVALIDARG; goto Exit; }
    grp->Deadband = *pPercentDeadband;
   }
 if (se->driver.ldCheckLocale && 
     se->driver.ldCheckLocale(&ctxt.cactx, dwLCID))
   GetLocaleID(&dwLCID);
 grp->grLCID = dwLCID;

 if (pTimeBias) grp->TimeBias = *pTimeBias;
 else
   {
    TIME_ZONE_INFORMATION tzi;
    tzi.Bias = 0;
    GetTimeZoneInformation(&tzi);
    grp->TimeBias = tzi.Bias;
   }

 if (szName)
   if (!*szName) szName = 0;
   else if (S_OK != grp->set_name(szName)) { hr = E_OUTOFMEMORY; goto Exit; }

// grp->sstate = loST_READY;
 hr = grp->QueryInterface(riid, (void**)ppUnk);
// grp->sstate = loST_DOWN;
 if (S_OK != hr) goto Exit;

 lock_write();
    if (!szName)
      {
       if (S_OK == (hr = mk_unique(tname, grp)))
         hr = grp->set_name(szName = tname);
      }
    else if (by_name(szName)) hr = OPC_E_DUPLICATENAME;

    if (S_OK == hr)
      if (servindex = add(grp))
        {
         do {
             if ((servhandle = ++unique_GroupHandle) == 0)
               servhandle = ++unique_GroupHandle;
            }
         while(by_handle(servhandle));

         grp->ServerHandle = servhandle;
         ostatus.dwGroupCount++;
        }
      else { hr = E_OUTOFMEMORY; /* delete grp; will be deleted by caller */ }
 unlock();

 if (phServerGroup) *phServerGroup = servhandle;

Exit:
 if (S_OK == hr)
   {
    UL_TRACE((LOG_SR("intAddGroup(%ls) i:%u h:%u /%p"),
              szName? szName: tname, servindex, servhandle, *ppUnk));
   }
 else
   {
     UL_TRACE((LOG_SR("intAddGroup(%ls) =%s"), loWnul(szName), loStrError(hr)));
//	 if (grp) delete grp;
    *ppUnk = 0;
   }

 return hr;
}
Beispiel #12
0
STDMETHODIMP LightOPCServer::ChangeBrowsePosition(
            /* [in] */ OPCBROWSEDIRECTION dwBrowseDirection,
            /* [string][in] */ LPCWSTR szString)
{
 HRESULT hr = S_OK;

 LO_CHECK_STATEz0("ChangeBrowsePosition");
 lock_browse();
   {
    loWchar brsep;
    int ii;

//UL_WARNING((LOG_SR("ChangeBrowsePosition->(%ls)(%ls)"), loWnul(browsepos.sb_str),loWnul(szString)));
    if (!(brsep = se->branch_sep))
      {
       hr = E_FAIL;
       UL_TRACE((LOG_SR("ChangeBrowsePosition() on the FLAT")));
      }
    else
      switch(dwBrowseDirection)
        {
      case OPC_BROWSE_UP:
        if (0 >= (ii = lo_name_level(brsep, browsepos.sb_str)))
          {
           hr = E_FAIL; /* already on root */
           UL_TRACE((LOG_SR("ChangeBrowsePosition() already on root")));
          }
        else
          {
           hr = set_browsepos(browsepos.sb_str,
                lo_name_levlen(brsep, browsepos.sb_str, ii - 1));
          }
        break;

      case OPC_BROWSE_DOWN:
        if (!szString || !*szString) hr = E_INVALIDARG;//loOPC_E_NOTFOUND;
        else if (0 > (ii = cat_browsepos(szString))) hr = E_OUTOFMEMORY;
        else if (!lo_browse_branch(se, browsepos.sb_str))
          {
           browsepos.sb_str[ii] = 0;
           hr = E_INVALIDARG;//loOPC_E_NOTFOUND;
          }
        break;

      case OPC_BROWSE_TO:
         if (!szString || !*szString) hr = set_browsepos(0);
         else
           hr = lo_browse_branch(se, szString)?
                       set_browsepos(szString): E_INVALIDARG;//loOPC_E_NOTFOUND;
         break;

      default: hr = E_INVALIDARG;
        UL_TRACE((LOG_SR("ChangeBrowsePosition() unknown direction")));
        break;
       }
   }
 UL_TRACE((LOG_SR("ChangeBrowsePosition(%X <%ls>) = %ls"),
      dwBrowseDirection, loWnul(szString), loWnul(browsepos.sb_str)));

 unlock_browse();

 if (S_OK != hr)
   {
    UL_INFO((LOG_SR("ChangeBrowsePosition(%X <%ls>) = %s"),
      dwBrowseDirection, loWnul(szString), loStrError(hr)));
   }

 LO_FINISH();
 return hr;
}
Beispiel #13
0
HRESULT LightOPCGroup::internalValidateItems(DWORD dwCount,
                                             OPCITEMDEF *pItemDefs,
                                             loTagId *tid, void **acpath,
		                                     OPCITEMRESULT **ppResults,
                                             HRESULT **ppErrors)
{
 HRESULT hr = S_OK;
 HRESULT *err = 0;
 OPCITEMRESULT *ir = 0;
 DWORD ii;
 loService *se;
 loTagEntry *tags;
 int free_tid = 0,
     inc_ap = 0,
     ai_goal = loDAIG_ADDITEM,
     am_mask;
 loCallerx cctx;
 loAA_DECLARE(sizeof(loTagId));

 if (!tid)
   {
    free_tid = 1;
    ai_goal = loDAIG_VALIDATE;
    tid = (loTagId*)loAA_ALLOC(dwCount * sizeof(loTagId));
   }
 if (acpath) inc_ap = 1;

 UL_TRACE((LOG_GRH("loGroup::intValidateItems(%lu, %p %p %p)"),
           dwCount, pItemDefs, ppResults, ppErrors));

 if (ppResults) *ppResults = 0;
 if (ppErrors) *ppErrors = 0;

 if (!dwCount || !pItemDefs || !ppResults)
   { hr = E_INVALIDARG; goto Return; }

 cctx = owner->ctxt;
 se = owner->se; tags = se->tags;

 err = (HRESULT*)loComAlloc(dwCount * sizeof(HRESULT));
 ir = (OPCITEMRESULT*)loComAlloc(dwCount * sizeof(OPCITEMRESULT));
 if (!err || !ir || !tid) { hr = E_OUTOFMEMORY; goto Return; }
 memset(ir, 0, dwCount * sizeof(OPCITEMRESULT));

 am_mask = owner->access_mode & loAM_RDONLY_ADD?
                (loOPC_RIGHTS & ~OPC_WRITEABLE): loOPC_RIGHTS;

 lw_rw_rdlock(&se->lkMgmt);
 for(ii = 0; ii < dwCount; ii++, acpath += inc_ap)
   if (tid[ii] = loFindItemID(se, &owner->ctxt.cactx, 1,
 		              pItemDefs[ii].szItemID,
		              pItemDefs[ii].szAccessPath,
                      pItemDefs[ii].vtRequestedDataType,
                      ai_goal,
                      acpath, &err[ii]))
     {
      loTagAttrib *ta = &tags[tid[ii]].attr;
      ir[ii].dwAccessRights = am_mask/*loOPC_RIGHTS*/ & ta->taRights;
      ir[ii].vtCanonicalDataType = taVTYPE(ta);
     }
   else hr = S_FALSE;
 lw_rw_unlock(&se->lkMgmt);

 lock_read();
   cctx.cta.vc_lcid = grLCID;
 unlock();

 for(ii = 0; ii < dwCount; ii++)
   if (S_OK == err[ii])
     {
      loTagAttrib *ta = &tags[tid[ii]].attr;
      if (loTF_EMPTY & ta->taFlags)
        { 
          err[ii] = OPC_E_INVALIDITEMID;
          tid[ii] = 0; hr = S_FALSE;
          goto LogErr;
        }
      else if (
        /*VT_EMPTY != pItemDefs[ii].vtRequestedDataType &&*/
         S_OK != (err[ii] = lo_checktype(&cctx, ta,
                                pItemDefs[ii].vtRequestedDataType)))
        { 
          /*err[ii] = OPC_E_BADTYPE */; 
         tid[ii] = 0; hr = S_FALSE; 
         goto LogErr;
        }
      else
         UL_TRACE((LOG_GR("intValidateItem(%ls)(%ls) = %u"),
                          loWnul(pItemDefs[ii].szItemID),
 		                  loWnul(pItemDefs[ii].szAccessPath),
			              tid[ii]));
     }
   else 
     {
LogErr: UL_NOTICE((LOG_GR("intValidateItem(%ls)(%ls) = %s"),
	                  loWnul(pItemDefs[ii].szItemID),
	   		          loWnul(pItemDefs[ii].szAccessPath),
			          loStrError(err[ii])));
     }

Return:

 if (free_tid)
   {
    loAA_FREE(tid);
   }

 if (FAILED(hr))
   {
    UL_TRACE((LOG_GRH("intValidateItems(%lu) = %s"), dwCount, loStrError(hr)));
   }
 else
   {
    *ppResults = ir, ir = 0;
    if (ppErrors) *ppErrors = err, err = 0;

    UL_TRACE((LOG_GRH("intValidateItems(%lu) = %s"), dwCount, loStrError(hr)));
   }
 if (ir)  loComFree(ir);
 if (err) loComFree(err);
 return hr;
}
Beispiel #14
0
STDMETHODIMP LightOPCServer::AddGroup(
		LPCWSTR szName,
		BOOL bActive,
		DWORD dwRequestedUpdateRate,
		OPCHANDLE hClientGroup,
		LONG *pTimeBias,
		FLOAT *pPercentDeadband,
		DWORD dwLCID,
		OPCHANDLE *phServerGroup,
		DWORD *pRevisedUpdateRate,
		REFIID riid,
		LPUNKNOWN *ppUnk
		)
{
 HRESULT hr = S_OK;
 LightOPCGroup *grp = 0;
 DWORD RevisedRate;
 OPCHANDLE ServerGroup;

 LO_CHECK_STATEz1("AddGroup", ppUnk);

 UL_TRACE((LOG_SR("AddGroup(%ls)"), loWnul(szName)));
 if (!ppUnk) { hr = E_INVALIDARG; goto Exit; }

// if (!phServerGroup || !pRevisedUpdateRate) { hr = E_INVALIDARG; goto Exit; }
 if (!phServerGroup) phServerGroup = &ServerGroup;
 if (!(grp = new LightOPCGroup) || !grp->iam_valid())
   { hr = E_OUTOFMEMORY; goto Exit; }
/*  need assign all group atributes */

 RevisedRate = loReviseUpdateRate(se, dwRequestedUpdateRate);

 hr = internalAddGroup(grp, szName, bActive,
			RevisedRate,
			hClientGroup,
			pTimeBias,
			pPercentDeadband,
			dwLCID,
			phServerGroup,
			riid,
			ppUnk);

Exit:
// if (!szName && grp) szName = grp->name;
 if (S_OK == hr)
   {
    if (pRevisedUpdateRate) *pRevisedUpdateRate = RevisedRate;
    if (RevisedRate != dwRequestedUpdateRate) hr = OPC_S_UNSUPPORTEDRATE;
    UL_NOTICE((LOG_SR("AddGroup(%ls) =%u (%umS (%umS) %g%%) %p"),
      loWnul(szName), *phServerGroup,
      (unsigned)RevisedRate, (unsigned)dwRequestedUpdateRate,
      pPercentDeadband? *pPercentDeadband: 0.0, *ppUnk));
   }
 else
   {
    UL_INFO((LOG_SR("AddGroup(%ls) =%s"), loWnul(szName), loStrError(hr)));
    if (grp) delete grp;
   }
 LO_FINISH();
 return hr;
}
Beispiel #15
0
lw_thrrettype loUpdatePipe(void *vse)
{
 loService *se = (loService *)vse;
 if (!loIS_VALID(se))
   {
    UL_ERROR((LOGID, "loUpdatePipe() prematurely terminated"));
    lw_RETURN;
   }
 UL_TRACE((LOGID, "loUpdatePipe() started..."));
 loThrControl_accept(&se->update_pipe);
 lw_mutex_lock(&se->update_pipe.lk);
 for(;; lw_conds_wait(&se->update_pipe.cond, &se->update_pipe.lk))
   if (0 != se->update_pipe.tstate)
     {
      if (0 > se->update_pipe.tstate) break; /* terminate thread */
      lw_mutex_unlock(&se->update_pipe.lk);
      lw_rw_wrlock(&se->lkPrim);
      lw_mutex_lock(&se->update_pipe.lk);
      if (0 > se->update_pipe.tstate)
        { lw_rw_unlock(&se->lkPrim); break; }/* terminate thread */
{       /* do actual update here */
 unsigned ii = se->lastused;
 loTagEntry *te = se->tags;
 loTagValue *ts = se->secondary;
 loTrid prim_changed = se->sec_trid;

 while(ii--)
   {
    te++;
    ts++;
    if (ts->tvTi)
      {
       if (ts->tvTi == loCH_TIMESTAMP)
         te->prim.tsTime = ts->tvState.tsTime;
       else
         {
          te->primChanged = prim_changed;
          te->prim = ts->tvState;
#if LO_KEEP_OLD_CACHE
          { HRESULT hr;
          if (S_OK != (hr = VariantCopy(&te->primValue, &ts->tvValue)))
            {
             LO_E_BADTYPE_QUAL(hr, te->prim.tsError, te->prim.tsQuality);
             UL_WARNING((LOGID, "%!l loUpdatePipe(VariantCopy())", hr));
          } }
#else
          VariantClear(&te->primValue);
          te->primValue = ts->tvValue;
          VARIANTINIT(&ts->tvValue);
#endif
         }
       ts->tvTi = 0;
      }
   }
}
      se->prim_trid = se->sec_trid;
#if 0 != LO_EV_TIMESTAMP
      if (se->ts_prim != se->ts_sec) 
        {
         freeX(se->ts_prim);
         se->ts_prim = se->ts_sec;
        }
      memcpy(se->ts_prim, 
             se->ts_prim + se->ts_size, 
             se->ts_size * sizeof(FILETIME));
#endif
      lw_rw_unlock(&se->lkPrim);
      se->update_pipe.tstate = 0;
      lw_condb_broadcast(&se->lkTridWait);
     }
 loThrControl_finish(&se->update_pipe);
 lw_mutex_unlock(&se->update_pipe.lk);
 UL_NOTICE((LOGID, "loUpdatePipe() finished"));

 lw_RETURN;
}
Beispiel #16
0
int loServiceCreate(loService **result, const loDriver *drv, unsigned tagcount)
{
    int rv = 0;
    size_t size;
    loService *se;

    if (!result) return EINVAL;
    *result = 0;
    if (!drv || 0 >= tagcount || 0 >= ++tagcount) return EINVAL;

    UL_DEBUG((LOGID, "structs: tE=%u tA=%u tD=%u tV=%u tS=%u tP=%u",
              sizeof(loTagEntry), sizeof(loTagAttrib), sizeof(loTagDetail),
              sizeof(loTagValue), sizeof(loTagState), sizeof(loTagPair)));

    size = sizeof(loService) +
           (sizeof(loTagEntry) + sizeof(loTagValue) + sizeof(lo_hash)) * tagcount;
    UL_TRACE((LOGID, "loCreate(%u) requested size = %u", tagcount - 1, size));

    se = (loService*)mallocX(size);
    if (!se)
    {
        UL_ERROR((LOGID, "loCreate(%u) requested size = %ud FAILED", tagcount, size));
        return ENOMEM;
    }
    se->iam = se;
    se->servlist = 0;
    se->serv_key = 0;
    se->shutdown = 0;

    se->initphase = 0;
    se->tag_count = 0;
    se->firstfree = 1; /* first entry is not used */
    se->lastused  = 0;
    se->lastnamed = 0;

    se->proplist = 0;
    se->proplist_count = 0;

    se->driver = *drv;

    se->cactx.ca_se = se;
    se->cactx.ca_se_arg = se->driver.ldDriverArg;
    se->cactx.ca_cli = 0;
    se->cactx.ca_cli_arg = 0;

    se->ts_prim = se->ts_sec = 0;
    se->ts_size = 0;

    se->log = 0;
#if 0 <= USE_LOG
    if (!lolog)
    {
        lolog = (unilog*)(se->log = INIT_LOG());
        UL_INFO((LOGID, "UNILOG initialization missed..."));
        UL_TRACE((LOGID, "loCreate(%u) requested size = %u", tagcount - 1, size));
    }
#endif

    se->ts_prim = se->ts_sec = (FILETIME*)mallocX(2 * sizeof(FILETIME));
    if (!se->ts_prim)
    {
        rv = ENOMEM;
        UL_ERROR((LOGID, "ts_prim init() FAILED"));
        goto Fail;
    }
    memset(se->ts_prim, 0, 2 * sizeof(FILETIME));
    se->ts_size = 1;

    if (rv = lo_proplist_init(se))
    {
        UL_ERROR((LOGID, "lo_proplist_init() FAILED"));
        goto Fail;
    }

    lo_setup_clock();
    if (se->driver.ldRefreshRate < 1)
    {
        se->driver.ldRefreshRate = lo_default_timegran(
                                       se->driver.ldRefreshRate_min < 1 ?
                                       &se->driver.ldRefreshRate_min : 0);
        if (se->driver.ldRefreshRate/*_min*/ < 1)
            se->driver.ldRefreshRate/*_min*/ = 16;
    }

    if (se->driver.ldRefreshRate_min < se->driver.ldRefreshRate)
        se->driver.ldRefreshRate_min = se->driver.ldRefreshRate;

    if (se->driver.ldQueueMax < 1) se->driver.ldQueueMax = 4; /* DEFAULT */

    if ((se->driver.ldFlags & loDf_EE_SFALSE) == loDf_EE_SFALSE)
        se->driver.ldFlags &= ~loDf_EE_SFALSE;

    se->wstrcmp = (se->driver.ldFlags & loDF_IGNCASE)? _wcsicmp: wcscmp;
    se->wstrncmp = (se->driver.ldFlags & loDF_IGNCASE)? _wcsnicmp: wcsncmp;
    se->wstrhash = (se->driver.ldFlags & loDF_IGNCASE)? lo_wcsihash: lo_wcshash;
#if 0
    se->wstrnhash = (se->driver.ldFlags & loDF_IGNCASE)? lo_wcsnihash: lo_wcsnhash;
#endif

    if (!se->driver.ldCurrentTime) se->driver.ldCurrentTime = ld_current_time;

    if (!se->driver.ldBranchSep ||
            0 >= mbtowc(&se->branch_sep, &se->driver.ldBranchSep, 1)) se->branch_sep = 0;
    UL_TRACE((LOGID, "Branch Separator = \\x%02X <%lc>\\x%02X",
              se->driver.ldBranchSep, se->branch_sep, se->branch_sep));

    se->tags = (loTagEntry*)(&se[1]);
    loTagEntry_init(se->tags, tagcount);
    se->secondary = (loTagValue*)(&se->tags[tagcount]);
    loTagValue_init(se->secondary, tagcount);
    se->tag_count = tagcount;
    se->name_hash = (lo_hash*)(&se->secondary[tagcount]);
    memset(se->name_hash, 0, sizeof(lo_hash) * tagcount);
    /* we assume VT_EMPTY === 0 */
    se->sec_trid = se->prim_trid = 0;
    /* se->prim_changed = 0; */

    se->tags[0].attr.taDetail = (loTagDetail*)mallocX(sizeof(loTagDetail));
    if (!se->tags[0].attr.taDetail)
    {
        UL_ERROR((LOGID, "loCreate(%u) taDetail FAILED", tagcount));
        rv = ENOMEM;
        goto Fail;
    }
    loTagDetail_init(se->tags[0].attr.taDetail);
    se->tags[0].attr.taFlags = loTt_DETAILS | loTF_EMPTY;
    se->tags[0].attr.taDetail->tdName[0] = 0;
    se->tags[0].attr.taRangecent = 0.0;

    if (rv = lw_rwlock_init(&se->lkMgmt, 0))
    {
        UL_ERROR((LOGID, "loCreate()::lkMgmt FAILED"));
        goto Fail;
    }
    se->initphase |= ifLKMGMT;

    if (rv = lw_rwlock_init(&se->lkPrim, 0))
    {
        UL_ERROR((LOGID, "loCreate()::lkPrim FAILED"));
        goto Fail;
    }
    se->initphase |= ifLKPRIM;

    if (rv = lw_mutex_init(&se->lkList, 0))
    {
        UL_ERROR((LOGID, "loCreate()::lkList FAILED"));
        goto Fail;
    }
    se->initphase |= ifLKLIST;

    if (rv = lw_mutex_init(&se->lkDr, 0))
    {
        UL_ERROR((LOGID, "loCreate()::lkDr FAILED"));
        goto Fail;
    }
    se->initphase |= ifLKDR;

    if (rv = lw_condb_init(&se->lkTridWait, 0))
    {
        UL_ERROR((LOGID, "loCreate()::lkTridWait FAILED"));
        goto Fail;
    }
    se->initphase |= ifTRWAIT;

    if (rv = loThrControl_init(&se->update_pipe))
    {
        UL_ERROR((LOGID, "loCreate()::loThr_init FAILED"));
        goto Fail;
    }
    se->initphase |= ifLKSEC;

    if (rv = loThrControl_start(&se->update_pipe, 0, loUpdatePipe, se))
    {
        UL_ERROR((LOGID, "loCreate()::loThr_start FAILED"));
        goto Fail;
    }

    se->cform_dataonly = RegisterClipboardFormat("OPCSTMFORMATDATA");
    se->cform_datatime = RegisterClipboardFormat("OPCSTMFORMATDATATIME");
    se->cform_writecompl = RegisterClipboardFormat("OPCSTMFORMATWRITECOMPLETE");

    *result = se;
    return 0;
Fail:
    UL_WARNING((LOGID, "%!e loCreate(%u) failed", rv, tagcount));
    loServiceDestroy(se);
    return rv;
}
loEnumIface<BASE,ITEM,IFACE>::~loEnumIface()
{
 UL_TRACE((LOGID, "loEnumIface::~%p", this));
 destroy_list();
}
Beispiel #18
0
int loInternalServiceDestroy(loService *se)
{
    int rv0, rv;
    unilog *log;

    UL_TRACE((LOGID, "loInternalServiceDestroy(%p)...", se));

    if (!loIS_VALID(se))
    {
        UL_ERROR((LOGID, "loInternalServiceDestroy(%p) illegal pointer", se));
        return EBADF;
    }
    se->iam = 0;
    log = (unilog*)se->log;
    se->log = 0;
    rv = 0;

    if ((se->initphase & ifLKSEC) &&
            (rv0 = loThrControl_destroy(&se->update_pipe)) && !rv) rv = rv0;

    if ((se->initphase & ifLKMGMT) &&
            (rv0 = lw_rwlock_destroy(&se->lkMgmt)) && !rv) rv = rv0;

    if ((se->initphase & ifLKPRIM) &&
            (rv0 = lw_rwlock_destroy(&se->lkPrim)) && !rv) rv = rv0;

    if ((se->initphase & ifLKDR) &&
            (rv0 = lw_mutex_destroy(&se->lkDr)) && !rv) rv = rv0;

    if ((se->initphase & ifLKLIST) &&
            (rv0 = lw_mutex_destroy(&se->lkList)) && !rv) rv = rv0;

    if ((se->initphase & ifTRWAIT) &&
            (rv0 = lw_condb_destroy(&se->lkTridWait)) && !rv) rv = rv0;

    se->initphase = 0;

    /* cleanup the CACHE & ATTRIB */
    if (se->secondary) loTagValue_clear(se->secondary, se->tag_count);
    if (se->tags)      loTagEntry_clear(se->tags, se->tag_count);
    se->tag_count = 0;
    lo_proplist_clear(se);

    se->ts_size = 0;
    if (se->ts_prim != se->ts_sec && se->ts_sec) freeX(se->ts_sec);
    se->ts_sec = 0;
    if (se->ts_prim) freeX(se->ts_prim);
    se->ts_prim = 0;

    freeX(se);

    if (rv) UL_WARNING((LOGID, "%!e loDelete() finished", rv));
    else UL_TRACE((LOGID, "loDelete() finished = %u", rv));
    {
#if 0 != LO_USE_MALLOCX
//    extern long mallocX_count;
        UL_WARNING((LOGID, "loDelete()::mallocX = %ld xobjref = %ld",
                    mallocX_count, lo_X_objcount));
#endif
        mallocX_trap();
    }

    if (log) unilog_Delete(log);

    return rv;
}
int lo_rio_requests(LightOPCServer *cli)
{
 loRequest *rq;
 loService *se = cli->se;

 while(rq = cli->q_req.req)
   {
    int operation = rq->operation;
    loTrid trid;

    if (loThrControl_outof01(&cli->async)) return -1;
    cli->q_req.req = rq->rq_next;
    if (operation & loRQ_OPER_IO)
      cli->q_req.metric_overload = 0;
    lw_mutex_unlock(&cli->async.lk);

    UL_TRACE((LOGID, "REQUEST Retreived %x / %x", operation, rq->upl.trqid));

    switch(operation & (loRQ_OPER_MASK | loRQ_DEVICE))
      {
#if LO_USE_BOTHMODEL
    case loRQ_OP_ADVISE:
      {
       void *aconn = 0;
       if (rq->conn_stream)
         {
          rq->upl.master_err = CoGetInterfaceAndReleaseStream(rq->conn_stream,
                                                             *rq->conn_iface,
                                                              &aconn);
          rq->conn_stream = 0;
         }
       else rq->upl.master_err = S_OK;
       if (SUCCEEDED(rq->upl.master_err))
         rq->upl.master_err = cli->sync_advise(operation, &aconn, rq->group_key);
       if (aconn) ((IUnknown*)aconn)->Release();
       if (operation & loRQ_SYNC)
         lo_req_put_bcast(&cli->q_ret, rq);
       else lo_req_free(rq);
      }
       break;

    case loRQ_OP_REMOVE_GROUP:
       rq->upl.master_err = cli->internalRemoveGroup(rq->group_key,
                                  operation & loRQ_OF_REMOVE_FORCE);
       if (operation & loRQ_SYNC)
         lo_req_put_bcast(&cli->q_ret, rq);
       else lo_req_free(rq);
       break;
#endif
/********************************************/

    case loRQ_OP_WRITE|loRQ_DEVICE:
       if (se->driver.ldWriteTags)
         {
          int rv;
          loLOCK_DRIVER(se);
          rv = se->driver.ldWriteTags(&rq->upl.rctx.cactx, rq->upl.used,
                                      rq->upl.tagpair, rq->upl.variant,
                                      rq->upl.errors, &rq->upl.master_err,
                                      rq->upl.rctx.cta.vc_lcid);
          loUNLOCK_DRIVER(se);
          if (rv == loDW_ALLDONE)
            {
             if (operation & loRQ_SYNC)
               lo_req_put_bcast(&cli->q_ret, rq);
             else
               {
                cli->send_callback(0, rq->group_key, &rq->upl, operation);
                lo_req_free(rq);
               }
             break;
            }
         }
// UL_ERROR((LOGID, "DEV WRITE failed"));
    case loRQ_OP_WRITE:
       rio_cache_write(se, &rq->upl);
       if (operation & loRQ_SYNC)
         lo_req_put_bcast(&cli->q_ret, rq);
       else
         {
          cli->send_callback(0, rq->group_key, &rq->upl, operation);
          lo_req_free(rq);
         }
       break;
/********************************************/

    case loRQ_OP_READ|loRQ_DEVICE:
       if (se->driver.ldReadTags /*&&
           !(cli->access_mode & (loAM_NOREAD_DEV |
                                 loAM_ERREAD_DEV))*/)
         {
          HRESULT m_err = rq->upl.master_err,
                  m_qual = rq->upl.master_qual;
          loLOCK_DRIVER(se);
          trid = se->driver.ldReadTags(&rq->upl.rctx.cactx, rq->upl.used,
                                       rq->upl.tagpair, rq->upl.variant, rq->upl.quality,
                                       rq->upl.timestamp, rq->upl.errors, &m_err, &m_qual,
                                       rq->upl.vartype, rq->upl.rctx.cta.vc_lcid);
          loUNLOCK_DRIVER(se);
          if (loDR_STORED == trid)
            {
             if (S_OK != m_err) rq->upl.master_err = S_FALSE;
             if (S_OK != m_qual) rq->upl.master_qual = S_FALSE;
             if (operation & loRQ_SYNC)
               lo_req_put_bcast(&cli->q_ret, rq);
             else
               {
                cli->send_callback(0, rq->group_key, &rq->upl, operation);
                lo_req_free(rq);
               }
             break;
            }
          else if (loDR_CACHED != trid) loTridWait(se, trid);
         }
    case loRQ_OP_READ:
       rio_cache_read(se, &rq->upl);
       if (operation & loRQ_SYNC)
         lo_req_put_bcast(&cli->q_ret, rq);
       else
         {
          cli->send_callback(0, rq->group_key, &rq->upl, operation);
          lo_req_free(rq);
         }
       break;
/********************************************/

    case loRQ_OP_REFRESH|loRQ_DEVICE:
       if (se->driver.ldReadTags /*&&
          !(cli->access_mode & (loAM_NOREAD_DEV |
                                loAM_ERREAD_DEV))*/)
         {
          loLOCK_DRIVER(se);
          trid = se->driver.ldReadTags(&rq->upl.rctx.cactx, 
                                       rq->upl.used, rq->upl.tagpair,
                                       0, 0, 0, 0, 0, 0, 0, 0
                                     /*rq->upl.variant, rq->upl.quality,
                                       rq->upl.timestamp, rq->upl.errors,
                                       &master_err, &master_qual,
                                       rq->upl.vartype, rq->upl.gr_lcid*/);
          loUNLOCK_DRIVER(se);
          if (loDR_CACHED != trid) loTridWait(se, trid);
         }
    case loRQ_OP_REFRESH:
       if (operation & loRQ_SYNC)
         UL_ERROR((LOGID, "SYNC REFRESH is invalid %x / %x", rq->operation, rq->upl.trqid));
       rio_refresh(cli, rq);
       break;
/********************************************/

    case loRQ_OP_CANCEL:
       cli->send_callback(0, rq->group_key, &rq->upl, operation);
       lo_req_free(rq);
       break;
/********************************************/

    default:
       UL_ERROR((LOGID, "BAD REQUEST %x / %x", rq->operation, rq->upl.trqid));
       lo_req_free(rq);
       break;
      }
#if 0
    if (rq) /*??*/
      {
       if (operation & loRQ_SYNC)
         lo_req_put_bcast(&cli->q_ret, rq);
       else
         {
          if (operation & loRQ_OPER_IO)
            cli->send_callback(0, rq->group_key, &rq->upl, operation);
          lo_req_free(rq);
         }
      }
#endif
    lw_mutex_lock(&cli->async.lk);
   }

 return 0;
}
Beispiel #20
0
STDMETHODIMP LightOPCGroup::Write(DWORD dwCount,
                                  OPCHANDLE  *phServer,
                                  VARIANT *pItemValues,
                                  HRESULT **ppErrors)
{
 HRESULT hr = S_OK;
 HRESULT *err = 0;
 unsigned items_ok = 0;
 loRequest *rq;

 LO_CHECK_STATEz1("SyncIO:Write", ppErrors);
 UL_TRACE((LOG_GRH("SyncIO:Write(%u)..."), dwCount));

 if (!phServer || !pItemValues || !dwCount)
   { hr = E_INVALIDARG; goto Return; }

 err = (HRESULT*)loComAlloc(dwCount * sizeof(HRESULT));
 rq = lo_req_alloc(dwCount, loUPL_variant /*| loUPL_errors*/ | loUPL_tagpair);
 if (!rq || !err) { hr = E_OUTOFMEMORY; goto Return; }
 rq->operation = loRQ_OP_WRITE | loRQ_SYNC | loRQ_DEVICE;
 rq->group_key = ServerHandle;
 rq->serv_key = owner->serv_key;
 rq->com_allocated = rq->upl.errors = err;
 loTagPair_init(rq->upl.tagpair, dwCount);
 rq->upl.rctx = owner->ctxt;

 lock_read();
 rq->upl.rctx.cta.vc_lcid = grLCID;

 if (owner->access_mode & loAM_RDONLY_OP)
   {
    unsigned ii;
    for(ii = 0; ii < dwCount; ii++) err[ii] = OPC_E_BADRIGHTS;
   }
 else
   {
    loService *se = owner->se;
    loTagEntry *tags = se->tags;
    loTagPair *tpl = rq->upl.tagpair;
//    HRESULT *errors = rq->upl.errors;
    VARIANT *variant = rq->upl.variant;
    LightOPCItem *it;
    unsigned ii;

    for(ii = 0; ii < dwCount; ii++, tpl++, pItemValues++)
      if (!(it = by_index(phServer[ii]))) err[ii] = OPC_E_INVALIDHANDLE;
      else
        {
         loTagEntry *te = &tags[it->tid];

#if 0 != LO_CHECK_RIGHTS
         if (!(OPC_WRITEABLE & te->attr.taRights)) err[ii] = OPC_E_BADRIGHTS;
         else
#endif
              if (VT_EMPTY == V_VT(pItemValues) ||/*) *errors = OPC_E_BADTYPE;
         else if (*/ S_OK == (err[ii] =
                       VariantCopy(&variant[ii], pItemValues)))
           {
            err[ii] = S_OK;
            tpl->tpTi = te->attr.taTi;
            tpl->tpRt = te->attr.taRt;
            tpl->tpAP = it->AcPath;
            items_ok++;
           }
         else UL_TRACE((LOG_GRH("SyncIO:Write(%u) [ %x / %x ] %s"),
               ii, V_VT(pItemValues), taVTYPE(&te->attr), loStrError(err[ii])));
       }
    rq->upl.used = dwCount;
   }
 unlock();
// rq->upl.used = dwCount;

 if (0 == items_ok)
   {
//    memcpy(err, rq->upl.errors, dwCount * sizeof(*err));
    rq->com_allocated = 0;
    lo_req_free(rq);
    hr = S_FALSE;
   }
 else
   {
    rq->upl.master_err = items_ok == dwCount? S_OK: S_FALSE;
    err = 0;
    if (rq = lo_req_put_sync(&owner->q_req, &owner->q_ret, rq))
      {
       hr = rq->upl.master_err;
//       memcpy(err, rq->upl.errors, dwCount * sizeof(*err));
       err = rq->upl.errors;
       rq->com_allocated = 0;
       lo_req_free(rq);
      }
    else hr = LO_E_SHUTDOWN;
   }

Return:
  if (SUCCEEDED(hr))
   {
    if (ppErrors) *ppErrors = err, err = 0;
//    if (items_ok != dwCount && hr == S_OK) hr = S_FALSE;
    UL_NOTICE((LOG_GRH("SyncIO:Write(%u) = %u Ok"), dwCount, items_ok));
   }
 else
   {
    UL_INFO((LOG_GRH("SyncIO:Write(%u) = %u /%s"),
               dwCount, items_ok, loStrError(hr)));
   }
 if (err) loComFree(err);
 LO_FINISH();
 return hr;
}
Beispiel #21
0
STDMETHODIMP LightOPCServer::BrowseOPCItemIDs(
            /* [in] */ OPCBROWSETYPE dwBrowseFilterType,
            /* [string][in] */ LPCWSTR szFilterCriteria,
            /* [in] */ VARTYPE vtDataTypeFilter,
            /* [in] */ DWORD dwAccessRightsFilter,
            /* [out] */ LPENUMSTRING *ppIEnumString)
{
 HRESULT hr = S_OK;
 loEnumString *ulist = 0;

 LO_CHECK_STATEz1("BrowseOPCItemIDs", ppIEnumString);

 if (szFilterCriteria && !*szFilterCriteria) szFilterCriteria = 0;
 if (!ppIEnumString ||
     dwBrowseFilterType != OPC_FLAT &&
     dwBrowseFilterType != OPC_BRANCH &&
     dwBrowseFilterType != OPC_LEAF) { hr = E_INVALIDARG; goto Return; }
 if (!(ulist = new loEnumString(0)))
   { hr = E_OUTOFMEMORY; goto Return; }

   {
    loTagId ti;
    lo_hash *hash_list = 0;
    loWchar brsep = se->branch_sep;
    BOOL casesens = 0 == (/*se->driver.*/ldFlags & loDF_IGNCASE);
    loWchar *brpos = 0;
    unsigned brlen = 0;
    int am_mask;
    loCallerx cctx = ctxt;

    loStringBuf aname;
    loStringBuf_init(&aname);
    lock_browse();
    if (browsepos.sb_str)
      {
       brlen = wcslen(browsepos.sb_str);
       brpos = loWstrdup(browsepos.sb_str);
      }
    cctx.cta.vc_lcid = ctxt.cta.vc_lcid;
    unlock_browse();
    if (brlen && !brpos)  { hr = E_OUTOFMEMORY; goto Return; }

    if (!brsep) dwBrowseFilterType = OPC_FLAT;
//    level = lo_name_level(brsep, browsepos.sb_str);
UL_TRACE((LOG_SR("Browse for: %u/%ls/ access %d"),
         brlen, loWnul(brpos), dwAccessRightsFilter));
    dwAccessRightsFilter &= loOPC_RIGHTS;
    if (dwAccessRightsFilter == (OPC_READABLE | OPC_WRITEABLE))
      dwAccessRightsFilter = 0;
    am_mask = dwAccessRightsFilter;
    if (access_mode & loAM_RDONLY_BROWSE) am_mask &= ~OPC_WRITEABLE;

//loMilliSec stst = lo_millisec();
    loLOCK_MGMT_O(&se->lkMgmt);

    for(ti = 0; ti = lo_browse_tag(se, ti, brpos, brlen, dwBrowseFilterType); ti++)
      {
       unsigned alen;
       loTagEntry *te = &se->tags[ti];
       const loWchar *item = te->attr.taName + brlen;
       if (!*item) continue; /* don't return itself */
       if (brsep == *item) item++;

       switch(dwBrowseFilterType)
         {
       case OPC_LEAF:
           if (wcschr(item, brsep)) continue;
           //if (1 < lo_name_level(brsep, item)) continue;

       case OPC_FLAT:
           alen = wcslen(item);

           if (dwAccessRightsFilter &&
              !(am_mask/*dwAccessRightsFilter*/ & te->attr.taRights)) continue;

           if (vtDataTypeFilter != VT_EMPTY &&
               S_OK != lo_checktype(&cctx, &te->attr,
                                    vtDataTypeFilter)) continue;

           break;

       case OPC_BRANCH:
           if (!wcschr(item, brsep)) continue;
          //if (1 >= lo_name_level(brsep, item)) continue;

           alen = lo_name_levlen(brsep, item, 1);
           {
            loWchar *uit;
            if (ulist->total &&
               !se->wstrncmp(item, uit = ulist->list[ulist->total - 1], alen) &&
                0 == uit[alen]) continue; /* duplicate */
           }
           break;
         }

       if (!loStringBuf_REALLOC(&aname, alen + 1))
         {
          hr = E_OUTOFMEMORY; break;
         }
       wcsncpy(aname.sb_str, item, alen); aname.sb_str[alen] = 0;

       if (szFilterCriteria &&
           !MatchPattern(aname.sb_str, szFilterCriteria, casesens))
         continue;

       if (OPC_BRANCH == dwBrowseFilterType)
         {
          unsigned uu;
          lo_hash a_hash = loSTRHASH(se, aname.sb_str);

          for(uu = ulist->total; uu; uu--)
            if (a_hash == hash_list[uu-1] &&
               !se->wstrcmp(aname.sb_str, ulist->list[uu-1]) ) break;
          if (uu) continue;

          if (!preallocX((void**)&hash_list,
               sizeof(*hash_list)*(ulist->total+1)))
            {
             hr = E_OUTOFMEMORY; break;
            }
          hash_list[ulist->total] = a_hash;
         }

//UL_DEBUG((LOG_SR("Browse %ls"), aname.sb_str));
       hr = ulist->add_item(&aname.sb_str);
       if (S_OK != hr) break;
      } /* end of for() */
   loUnLOCK_MGMT_O(&se->lkMgmt);
/*
UL_WARNING((LOG_SR("BrowseOPC <%ls> %d  TIME %d"),
           loWnul(brpos), ulist->total, lo_millisec() - stst));
//*/
    if (brpos) freeX(brpos);
    if (hash_list) freeX(hash_list);
    loStringBuf_clear(&aname);
   }

Return:

 if (S_OK == hr &&
     S_OK == (hr = ulist->initiate(&otrk)))
   {
    *ppIEnumString = (LPENUMSTRING)ulist;
    UL_NOTICE((LOG_SR("BrowseOPCItemIDs() = %u"), ulist->total));
    if (!ulist->total) { ENUM_EMPTY(hr, ldFlags, ppIEnumString); }
   }
 else
   {
    if (ulist) { delete ulist; ulist = 0; }
    UL_INFO((LOG_SR("BrowseOPCItemIDs() = %s"), loStrError(hr)));
   }

 LO_FINISH();
 return hr;
}
Beispiel #22
0
STDMETHODIMP LightOPCGroup::CloneGroup(LPCWSTR szName,	REFIID riid, LPUNKNOWN *ppUnk)
{
 HRESULT hr = S_OK;
 LightOPCGroup *grp = 0;
 OPCHANDLE serverhandle;

 LO_CHECK_STATEz1("CloneGroup", ppUnk);
 UL_TRACE((LOG_GRH("CloneGroup(-> %ls)"), loWnul(szName)));
 if (!ppUnk) { hr = E_INVALIDARG; goto Exit; }

 if (!(grp = new LightOPCGroup) || !grp->iam_valid())
   { hr = E_OUTOFMEMORY; goto Exit; }

 lock_read();

    if (szName && owner->by_name(szName)) hr = OPC_E_DUPLICATENAME;
    else
      {
       unsigned ii;
       LightOPCItem *proto;
/* do cloning of items here */
       for(ii = 0; ii < itl.gl_count; ii++)
         if (proto = (LightOPCItem*)itl.gl_list[ii])
           {
            LightOPCItem *newby = new LightOPCItem;
            if (newby)
              {
               newby->convtype = proto->convtype;
               newby->tid = proto->tid;
               newby->AcPath = proto->AcPath;
               newby->bActive = proto->bActive;
               newby->hClient = proto->hClient;
               newby->vtRequestedDataType = proto->vtRequestedDataType;
               if (S_OK != (hr = newby->set_accpath(proto->szAccessPath)) ||
                   S_OK != (hr = newby->set_itemid(proto->szItemID)))
                 { delete newby; break; }
               if (!grp->add(newby))
                 { delete newby; hr = E_OUTOFMEMORY; break; }
               newby->Quality = -1;
               if (newby->bActive) grp->active_count++;
               else newby->Quality = OPC_QUALITY_OUT_OF_SERVICE;
              }
            else { hr = E_OUTOFMEMORY; break; }
           }
      }
 unlock();

 if (S_OK == hr)
   hr = owner->internalAddGroup(grp, szName, 0/*bActive*/,
                  UpdateRate,
                  ClientHandle,
                  &TimeBias,
                  &Deadband,
                  grLCID,
                  &serverhandle,
                  riid,
                  ppUnk);
Exit:
 if (S_OK == hr)
   {
    UL_NOTICE((LOG_GRH("CloneGroup(-> %ls) =%u /%p"),
	              loWnul(szName), serverhandle, *ppUnk));
   }
 else
   {
    UL_INFO((LOG_GRH("CloneGroup(-> %ls) =%s"),
                      loWnul(szName), loStrError(hr)));
    if (grp) delete grp;
   }

 LO_FINISH();
 return hr;
}