Пример #1
0
static void gmem_free(HGLOBAL *hg)
{
 if (*hg && GlobalFree(*hg))
   {
    UL_ERROR((LOGID, "%!L gmem_free(%X) FAILED", *hg));
   }
 *hg = 0;
}
HRESULT MyClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj)
{
	ATLASSERT(ppvObj);
	if (NULL == ppvObj)
	{
		return E_INVALIDARG;
	}
	*ppvObj = NULL;

	HRESULT hr = S_OK;
	IUnknown *server = NULL;
	IUnknown *inner = NULL;

	if (NULL == DataService::Instance())
	{
		return E_POINTER;
	}

	if (loClientCreate_agg(DataService::Instance().get(), (loClient**)&server, 
		pUnkOuter, &inner,
		0, &vendor, a_server_finished, NULL/*cuserid*/))
	{
		// server remove
		UL_ERROR((Log::Instance().get(), 0, "myClassFactory::loClientCreate_agg() failed"));
		hr = E_OUTOFMEMORY;
	}
	else if (pUnkOuter)
	{
		*ppvObj = (void*)inner; // aggregation requested
	}	
	else // no aggregation
	{
		hr = server->QueryInterface(riid, ppvObj); // Then 2 (if success)
		server->Release(); // Then 1 (on behalf of client) or 0 (if QI failed)
	}

	if (SUCCEEDED(hr))
	{
		loSetState(DataService::Instance().get(), (loClient*)server,
			loOP_OPERATE, (int)OPC_STATUS_RUNNING, "Finished by client");
		UL_INFO((Log::Instance().get(), 0, "OPC service is started."));
	}

#ifdef __EVAL__
	boost::shared_ptr<boost::thread> licThread(new boost::thread(LicenseTimeout)); 
#endif

	return hr;
}
Пример #3
0
static void StrToIID(GUID* iid, const char* str)
{
 int data[8];
 sscanf(str, "{%08X-%04hX-%04hX-%02X%02X-%02X%02X%02X%02X%02X%02X}",
	      &iid->Data1, &iid->Data2, &iid->Data3,
              &data[0], &data[1],
              &data[2], &data[3], &data[4], &data[5], &data[6], &data[7]);
 iid->Data4[0] = data[0];
 iid->Data4[1] = data[1];
 iid->Data4[2] = data[2];
 iid->Data4[3] = data[3];
 iid->Data4[4] = data[4];
 iid->Data4[5] = data[5];
 iid->Data4[6] = data[6];
 iid->Data4[7] = data[7];

 char b2[80];
 IIDtoStr(b2, iid);
 if (stricmp(b2, str)) UL_ERROR((LOGID, "IID_CONV: %s -> %s", str, b2));
}
Пример #4
0
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);
}
Пример #5
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);
}
Пример #6
0
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;
}
Пример #7
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;
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
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;
}
Пример #11
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;
}
Пример #12
0
int lo_OnDataChange1(loUpdList *upl, OPCHANDLE hClient, unsigned cform,
                     int with_time, IAdviseSink *ias, HGLOBAL *gmem, unsigned *hint_dsize)
{
 HGLOBAL fakegmem = 0;
 unsigned hdrsize, totalsize, ihdr_size, datasize;
 unsigned ii, itcount = upl->used;
 loUpdList lup = *upl;

 ihdr_size = with_time? sizeof(OPCITEMHEADER1): sizeof(OPCITEMHEADER2);
 hdrsize = sizeof(OPCGROUPHEADER) + itcount * ihdr_size;
 datasize = 0;

 if (hint_dsize && *hint_dsize) datasize = *hint_dsize;
 else
   {
    for(ii = itcount; ii--;)
      {
       datasize += loVariantSize(&lup.variant[ii]);
      }
    if (hint_dsize) *hint_dsize = datasize;
   }

 totalsize = hdrsize + datasize;

 if (!gmem) gmem = &fakegmem;
 if (!gmem_realloc(gmem, totalsize))
   {
    itcount = 0;
    hdrsize = sizeof(OPCGROUPHEADER);
    if (!gmem_realloc(gmem, hdrsize))
      {
       UL_ERROR((LOGID, "%!L Trasaction %X ABORTED due gmem_alloc(%u)",
                 lup.trqid, totalsize));
       return -1;
      }
    UL_WARNING((LOGID, "%!L Trasaction %X Failed due gmem_alloc(%u)",
                 lup.trqid, totalsize));
    totalsize = hdrsize;
    lup.master_err = E_OUTOFMEMORY;
   }

{
 char *glob, *glob0, *ihdr;
 OPCGROUPHEADER *gh;
 FILETIME faketime, *timest = &faketime;
 unsigned timest_inc = 0;

 glob = glob0 = (char*)GlobalLock(*gmem);
 gh = (OPCGROUPHEADER*)glob;
 ihdr = (char*)&gh[1];
 glob += hdrsize;

 if (with_time)
   timest_inc = sizeof(OPCITEMHEADER1),
   timest = &((OPCITEMHEADER1*)ihdr)->ftTimeStampItem;

 gh->dwSize = totalsize;
 gh->dwItemCount = itcount;
 gh->hClientGroup = hClient;
 gh->dwTransactionID = lup.trqid;

 for(ii = 0; ii < itcount; ii++)
   {
    ((OPCITEMHEADER1*)ihdr)->wReserved = 0;
    ((OPCITEMHEADER1*)ihdr)->dwValueOffset = glob - glob0;
    ((OPCITEMHEADER1*)ihdr)->hClient  = lup.opchandle[ii];
    ((OPCITEMHEADER1*)ihdr)->wQuality = lup.quality[ii];
    loVariantPack((void**)&glob, &lup.variant[ii]);
    *timest = lup.timestamp[ii];
    timest = (FILETIME*)(((char*)timest) + timest_inc);
    ihdr += ihdr_size;
   }

 gh->hrStatus = lup.master_err != S_OK?
                lup.master_err: lup.master_qual;

 if ((unsigned)(glob - glob0) != totalsize)
   {
    UL_ERROR((LOGID, "Transaction:%X datasize mismatch %u %u",
                      lup.trqid, glob - glob0, totalsize));
   }
 GlobalUnlock(*gmem);
}
{
 STGMEDIUM stgm;
 FORMATETC form;

 form.cfFormat = cform;
 form.dwAspect = DVASPECT_CONTENT;
 form.ptd = NULL;
 form.tymed = TYMED_HGLOBAL;
 form.lindex = -1;
 stgm.tymed = TYMED_HGLOBAL;
 stgm.STGM_hGlobal = *gmem;
 stgm.pUnkForRelease = DUMMY_UNKNOWN;

 UL_DEBUG((LOGID, "OnDataChange1:%s-time(%u)...%p{ %X",
                  with_time? "with": "without", 
                  itcount, ias, *gmem));
 ias->OnDataChange(&form, &stgm);
 UL_DEBUG((LOGID, "OnDataChange()...}"));
}
 gmem_free(&fakegmem);

 return FAILED(lup.master_err)? -1: 0;
}
Пример #13
0
int lo_OnWriteComplete1(loUpdList *upl, OPCHANDLE hClient, unsigned cform,
                        IAdviseSink *ias, HGLOBAL *gmem)
{
 HGLOBAL fakegmem = 0;
 unsigned datasize;
 unsigned ii, itcount = upl->used;
 loUpdList lup = *upl;

 datasize = sizeof(OPCGROUPHEADERWRITE) + itcount * sizeof(OPCITEMHEADERWRITE);

 if (!gmem) gmem = &fakegmem;
 if (!gmem_realloc(gmem, datasize))
   {
    itcount = 0;
    datasize = sizeof(OPCGROUPHEADERWRITE);
    if (!gmem_realloc(gmem, datasize))
      {
       UL_ERROR((LOGID, "%!L Trasaction %X ABORTED due gmem_alloc(%u)",
                 lup.trqid, datasize));
       return -1;
      }
    UL_WARNING((LOGID, "%!L Trasaction %X Failed due gmem_alloc(%u)",
                 lup.trqid, datasize));
    lup.master_err = E_OUTOFMEMORY;
   }

{
 OPCGROUPHEADERWRITE *gh;
 OPCITEMHEADERWRITE *ihdr;

 gh = (OPCGROUPHEADERWRITE*)GlobalLock(*gmem);
 ihdr = (OPCITEMHEADERWRITE*)&gh[1];

 gh->dwItemCount = itcount;
 gh->hClientGroup = hClient;
 gh->dwTransactionID = lup.trqid;
 gh->hrStatus = lup.master_err;

 for(ii = 0; ii < itcount; ii++, ihdr++)
   {
    ihdr->hClient = lup.opchandle[ii];
    ihdr->dwError = lup.errors[ii];
// UL_DEBUG((LOGID, "OnWriteComplete(%u : %X/%X)", itcount, ihdr->dwError, gh->hrStatus));
   }

 if ((unsigned)((char*)ihdr - (char*)gh) != datasize)
   {
    UL_ERROR((LOGID, "Transaction:%X datasize mismatch %u %u",
                      lup.trqid, (char*)ihdr - (char*)gh, datasize));
   }
 UL_DEBUG((LOGID, "OnWriteComplete(%u : %X/%X)", itcount, gh->hrStatus, lup.master_err));
 GlobalUnlock(*gmem);
}
{
 STGMEDIUM stgm;
 FORMATETC form;

 form.cfFormat = cform;
 form.dwAspect = DVASPECT_CONTENT;
 form.ptd = NULL;
 form.tymed = TYMED_HGLOBAL;
 form.lindex = -1;
 stgm.tymed = TYMED_HGLOBAL;
 stgm.STGM_hGlobal = *gmem;
 stgm.pUnkForRelease = DUMMY_UNKNOWN;

 ias->OnDataChange(&form, &stgm);
 UL_DEBUG((LOGID, "OnWriteComplete()...}"));
}
 gmem_free(&fakegmem);

 return FAILED(lup.master_err)? -1: 0;
}
Пример #14
0
int ZSDriver::WriteTags(const loCaller *ca,
						unsigned count, loTagPair taglist[],
						VARIANT values[], HRESULT error[], HRESULT *master, LCID lcid)
{
	// A guard but unsafe
	if (!isKeepRunning || NULL == dataService)
	{
		return loDW_ALLDONE;
	}

	const ZSSerialProtocol::DataSetDef& dataDef = protocol->GetDataSetInfo();
	unsigned fixed = dataDef.size();
	const std::vector<ZSSerialSetting>& ports = protocol->GetPortSetting();
	std::vector<unsigned> segments;
	segments.push_back(0);
	for (std::size_t i = 0; i < ports.size(); ++i)
	{
		unsigned temp = ports.at(i).stations.size() * fixed;
		segments.push_back(temp + segments.at(i));
	}

	for (unsigned i = 0; i < count; ++i)
	{
		std::size_t whichPort = 0;
		unsigned drvIndex = reinterpret_cast<unsigned>(taglist[i].tpRt);
		for (; whichPort < segments.size() - 1; ++whichPort)
		{
			if (drvIndex < segments.at(whichPort + 1))
			{
				break; // the port is matched
			}
		}
		if (segments.size() - 1 == whichPort)
		{
			continue; // no port is matched. Go to the next tag
		}

		unsigned short whichStation = (drvIndex - segments.at(whichPort)) / fixed;
		unsigned short index = (drvIndex - segments.at(whichPort)) % fixed;

		ZSSerialProtocol::DataSetDef::const_iterator iter = dataDef.begin();
		std::advance(iter, index);
		_ASSERTE(iter != dataDef.end());
		if (iter == dataDef.end())
		{
			continue; // error, we do nothing, add log here.
		}

		// check whether the stations is enabled
		if (ZSSerialProtocol::ZS_DEV_DISABLED == 
			ports.at(whichPort).stations.at(whichStation).second && 
			protocol->GetFaultSignalDataIndex() != index)
		{
			continue; // the station is disabled, jump to the next tag.
		}

		HRESULT hr;
		CComVariant var = values[i];
		{
			// write data or command
			boost::upgrade_lock<boost::shared_mutex> upLock(*rwMutex);
			boost::upgrade_to_unique_lock<boost::shared_mutex> uniLock(upLock);

			try
			{
				if (iter->first < ZSDRV_COMMON_CMD_START) // write data
				{
					ZSDataItem dataItem;
					dataItem.index = iter->first;
					if (iter->second.get<ZSSerialProtocol::ZS_DATA_TYPE_INDEX>())
					{
						hr = var.ChangeType(VT_R8);
						_ASSERTE(S_OK == hr);
						if (S_OK != hr)
						{
							continue; // add log here
						}
						dataItem.variant = var.dblVal;
					}
					else
					{
						hr = var.ChangeType(VT_UI4);
						_ASSERTE(S_OK == hr);
						if (S_OK != hr)
						{
							continue; // add log here
						}
						dataItem.variant = var.uintVal;
					}
					serials->at(whichPort)->WriteData(dataItem, 
						ports.at(whichPort).stations.at(whichStation).first);
				}
				else if (protocol->GetFaultSignalDataIndex() != index)// write the common command
				{
					hr = var.ChangeType(VT_UI4);
					_ASSERTE(S_OK == hr);
					if (S_OK != hr)
					{
						continue; // add log here
					}
					if (var.uintVal > 0)
					{
						serials->at(whichPort)->WriteCommand(iter->first, 
							ports.at(whichPort).stations.at(whichStation).first);
					}
					else
					{
						continue;
					}
				}
				else  // check whether the restore the device healthy status is set.	
				{
					hr = var.ChangeType(VT_UI4);
					_ASSERTE(S_OK == hr);
					if (S_OK == hr && 0 == var.uintVal)
					{
						protocol->UpdateStationStatus(whichPort, whichStation, ZSSerialProtocol::ZS_DEV_OK);
					}
					else
					{
						continue;
					}
				}
			}
			catch (timeout_exception& e)
			{
				UL_ERROR((Log::Instance().get(), 0, "WriteData() error: %s", e.what()));		
			}
			catch (boost::system::system_error& e)
			{
				UL_ERROR((Log::Instance().get(), 0, "WriteData() error: %s", e.what()));
			}

		}

		FILETIME ft;
		GetSystemTimeAsFileTime(&ft);
		tags->at(drvIndex).tvState.tsTime = ft;
		tags->at(drvIndex).tvState.tsQuality = OPC_QUALITY_GOOD;
		tags->at(drvIndex).tvValue = var;
		{
			boost::lock_guard<boost::mutex> guard(*mutex);
			loCacheUpdate(dataService.get(), 1, &(tags->at(drvIndex)), 0);
		}
	}

	return loDW_ALLDONE;
}
Пример #15
0
// Refresh data worker function
void ZSDriver::RefreshDataTask(boost::shared_ptr<loService> service, unsigned serialIndex)
{
	boost::shared_ptr<ZSSerial> serial = serials->at(serialIndex);
	const std::vector<std::pair<unsigned char, unsigned short> >& stations =
		protocol->GetPortSetting().at(serialIndex).stations;
	std::string devName = protocol->GetPortSetting().at(serialIndex).devName;
	std::size_t gpOneCount = protocol->GetReadDataCmd().at(0).info.size();
	std::size_t gpTwoCount = protocol->GetReadDataCmd().at(1).info.size();
	std::size_t dataTotalCount = protocol->GetDataSetInfo().size();

	unsigned refreshBase = protocol->GetReadDataCmd().at(ZSDRV_READ_DATA_GROUP_I).refresh;
	refreshBase = (0 == refreshBase) ? REFRESH_MIN : refreshBase; // at lease REFRESH_MIN
	unsigned interval = 
		protocol->GetReadDataCmd().at(ZSDRV_READ_DATA_GROUP_II).refresh / refreshBase;
	interval = // at least ZSDRV_READDATA_GROUP_SWITCH_INTERVAL
		(interval < ZSDRV_READDATA_GROUP_SWITCH_INTERVAL) ? ZSDRV_READDATA_GROUP_SWITCH_INTERVAL : interval;

	std::size_t grpStartOffset = 0;
	for (std::size_t i = 0; i < serialIndex; i++)
	{
		grpStartOffset += 
			dataTotalCount * protocol->GetPortSetting().at(i).stations.size();
	}

	while (isKeepRunning)
	{
		for (std::size_t i = 0; i < stations.size(); ++i)
		{
			// the station is disabled
			if (ZSSerialProtocol::ZS_DEV_DISABLED == stations.at(i).second)
			{
				::Sleep(REFRESH_MIN);
				continue;
			}

			unsigned dataGroup;
			if (interval > 0)
			{
				dataGroup = ZSDRV_READ_DATA_GROUP_I;
			}
			else
			{
				dataGroup = ZSDRV_READ_DATA_GROUP_II;
			}

			try // refresh data
			{
				RefreshDataSubJob(service, serial, stations.at(i).first, 
					dataGroup, grpStartOffset + i * dataTotalCount);
				::Sleep(refreshBase);
				protocol->UpdateStationStatus(serialIndex, i, ZSSerialProtocol::ZS_DEV_OK); // restore
			}
			catch (timeout_exception& e)
			{
				NotifyDevFault(service, serialIndex, i, grpStartOffset + i * dataTotalCount);
				UL_ERROR((Log::Instance().get(), 0, "ReadData error: %s - %s", 
					devName.c_str(), e.what() ));
			}
			catch (boost::system::system_error& e)
			{
				NotifyDevFault(service, serialIndex, i, grpStartOffset + i * dataTotalCount);
				UL_ERROR((Log::Instance().get(), 0, "ReadData error: %s - %s", 
					devName.c_str(), e.what() ));		
			}
		}
		if (0 == interval)
		{
			interval = ZSDRV_READDATA_GROUP_SWITCH_INTERVAL;
		}
		else
		{
			interval--;
		}
	}
}