unsigned loObjTracker::ot_disconnect_all(int remove) { unsigned count = 0; loObjTrack *tail; ot_lock(); UL_DEBUG((LOGID, "ot_disconnect(%u) %p started", remove, ot_first)); if (tail = ot_first) { ot_first = 0; tail->ot_iam = &tail; while(tail) { loObjTrack *cur = tail; cur->unlocked_remove(); if (!remove) cur->unlocked_connect(this); LO_CO_DISCONNECT(cur->ot_unk, 0); count++; } } UL_DEBUG((LOGID, "ot_disconnect(%u) finished", count)); ot_unlock(); return count; }
HRESULT LightOPCServer::internalRemoveGroup(unsigned groupHandleID, int bForce) { #if 1 HRESULT hr = loOPC_E_INVALIDHANDLE; #else HRESULT hr = loOPC_E_NOTFOUND; #endif unsigned ii; UL_DEBUG((LOG_SR("internalRemoveGroup(%u %s)"), groupHandleID, bForce? "FORCE": "")); WR_lock(&lk_remove); lock_write(); if (ii = by_handle(groupHandleID)) { hr = del(ii, bForce && !(/*se->driver.*/ldFlags & loDf_NOFORCE)) ? OPC_S_INUSE: S_OK; ostatus.dwGroupCount--; } unlock(); lw_rw_unlock(&lk_remove); UL_DEBUG((LOGID, "%!l internalRemoveGroup(%u %s) =", hr, groupHandleID, bForce? "FORCE": "")); return hr; }
STDMETHODIMP QueryInterface(REFIID iid, LPVOID *ppInterface) { if (ppInterface == NULL) return E_INVALIDARG; if (iid == IID_IUnknown || iid == IID_IClassFactory) { UL_DEBUG((LOGID, "myClassFactory::QueryInterface() Ok")); *ppInterface = this; AddRef(); return S_OK; } UL_DEBUG((LOGID, "myClassFactory::QueryInterface() Failed")); *ppInterface = NULL; return E_NOINTERFACE; }
void loShutdownConn_clear(loShutdownConn *sc) { if (sc->request) sc->request->Release(); UL_DEBUG((LOGID, "loShutdownConn_clear(%p)", sc->request)); if (sc->reason) freeX(sc->reason); loShutdownConn_init(sc); }
STDMETHODIMP LockServer(BOOL fLock) { UL_DEBUG((LOGID, "myClassFactory::LockServer(%d)", fLock)); if (fLock) serverAdd(); else serverRemove(); return S_OK; }
void loObjTrack::ot_remove(void) { if (ot_iam && ot_tr) { loObjTracker *list = ot_tr; UL_DEBUG((LOGID, "ot_remove(%p->%p)", ot_iam, ot_unk)); list->ot_lock(); unlocked_remove(); list->ot_unlock(); } }
STDMETHODIMP loEnum<BASE,ITEM,IFACE>::Clone(BASE **ppenum) { HRESULT hr; TYPE *ne; UL_DEBUG((LOGID, "loEnum??::Clone(%p)", this)); if (!ppenum) return E_INVALIDARG; *ppenum = 0; ne = clone(); if (!ne) return E_OUTOFMEMORY; if (S_OK == (hr = ne->initiate(ot_tracker()))) *ppenum = ne; else delete ne; return S_OK; }
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; }
HRESULT manageOPCDAcat(const GUID *service, int remove) { HRESULT hr, hri; ICatRegister *pcr; hri = CoInitialize(0); hr = CoCreateInstance( #ifndef __cplusplus & #endif CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, #ifndef __cplusplus & #endif IID_ICatRegister, (void **)&pcr ); if (FAILED(hr)) { UL_INFO((LOGID, "%!l FAILED to get ICatRegister", hr)); } else { CATID catid[2]; if (0 == remove) { CATEGORYINFO catinf[2]; catinf[0].catid = CATID_OPCDAServer10; wcscpy(catinf[0].szDescription, L"OPC Data Access Servers Version 1.0"); catinf[0].lcid = 0x0409; catinf[1].catid = CATID_OPCDAServer20; wcscpy(catinf[1].szDescription, L"OPC Data Access Servers Version 2.0"); catinf[1].lcid = 0x0409; #ifdef __cplusplus hr = pcr->RegisterCategories(2, catinf); #else hr = pcr->lpVtbl->RegisterCategories(pcr, 2, catinf); #endif if (FAILED(hr)) UL_INFO((LOGID, "%!l FAILED ICatRegister::RegisterCategories()", hr)); } catid[0] = CATID_OPCDAServer10; catid[1] = CATID_OPCDAServer20; #ifdef __cplusplus hr = remove? pcr->UnRegisterClassImplCategories(*service, 2, catid): pcr->RegisterClassImplCategories(*service, 2, catid); pcr->Release(); #else hr = remove? pcr->lpVtbl->UnRegisterClassImplCategories(pcr, service, 2, catid): pcr->lpVtbl->RegisterClassImplCategories(pcr, service, 2, catid); pcr->lpVtbl->Release(pcr); #endif if (FAILED(hr)) UL_INFO((LOGID, "%!l FAILED ICatRegister::%sRegisterClassImplCategories()", hr, remove? "Un": "")); } if (SUCCEEDED(hri)) CoUninitialize(); UL_DEBUG((LOGID, "%!l ICatRegister::%sRegister", hr, remove? "Un": "")); return hr; }
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; }
int LightOPCServer::send_callback(LightOPCGroup *grp, unsigned group_key, loUpdList *upl, int advmask) { int tr = 0; IOPCDataCallback *c_databack = 0; IAdviseSink *c_datatime = 0, *c_dataonly = 0, *c_writecomp = 0; unsigned cform_dtime, cform_donly, cform_wrcompl; OPCHANDLE client_handle; // UL_DEBUG((LOGID, "send_notify(){...")); if (!upl->used) { if (!upl->trqid) return 0; if (S_OK == upl->master_err) upl->master_err = S_FALSE; } if (FAILED(upl->master_err)) upl->master_qual = S_FALSE; if (!grp) { lock_read(); if (0 == (grp = by_handle_g(group_key))) { unlock(); UL_INFO((LOGID, "send_callback(%x) FAILED: No such group")); return 0; } } #if LO_USE_BOTHMODEL && 0 else group_key = grp->ServerHandle; #endif client_handle = grp->ClientHandle; /* There is only client_sched() thread allowed to change connection info under read_lock ! */ if ((advmask & loRQ_CONN_DATABACK) && grp->conn_databack) loGET_IFACE(c_databack, grp->conn_databack, IOPCDataCallback, grp->initphase); if (advmask & (loRQ_CONN_DATA_1 | loRQ_CONN_WRITECOMPL)) { if ((advmask & loRQ_CONN_DATATIME) && grp->conn_datatime) { cform_dtime = se->cform_datatime; loGET_IFACE(c_datatime, grp->conn_datatime, IAdviseSink, grp->initphase); /* ?? advise_present &= ~loRQ_CONN_DATATIME */ } if ((advmask & loRQ_CONN_DATAONLY) && grp->conn_dataonly) { cform_donly = se->cform_dataonly; loGET_IFACE(c_dataonly, grp->conn_dataonly, IAdviseSink, grp->initphase); /* ?? advise_present &= ~loRQ_CONN_DATAONLY */ } if ((advmask & loRQ_CONN_WRITECOMPL) && grp->conn_writecompl) { cform_wrcompl = se->cform_writecompl; loGET_IFACE(c_writecomp, grp->conn_writecompl, IAdviseSink, grp->initphase); /* ?? advise_present &= ~loRQ_CONN_WRITECOMPL */ } } unlock(); // UL_DEBUG((LOGID, "send_notify() #3")); if (c_databack) { HRESULT hr = E_INVALIDARG; switch(advmask & loRQ_OPER_MASK) { case loRQ_OP_REFRESH: hr = c_databack->OnDataChange(upl->trqid, client_handle, upl->master_err, upl->master_qual, upl->used, upl->opchandle, upl->variant, upl->quality, upl->timestamp, upl->errors); break; case loRQ_OP_READ: hr = c_databack->OnReadComplete(upl->transaction_id, client_handle, upl->master_err, upl->master_qual, upl->used, upl->opchandle, upl->variant, upl->quality, upl->timestamp, upl->errors); break; case loRQ_OP_WRITE: hr = c_databack->OnWriteComplete(upl->transaction_id, client_handle, upl->master_err, upl->used, upl->opchandle, upl->errors); break; case loRQ_OP_CANCEL: hr = c_databack->OnCancelComplete(upl->transaction_id, client_handle); break; } c_databack->Release(); if (S_OK == hr) { tr++; UL_DEBUG((LOGID, "OnDataChange2(0x%X) Ok", advmask)); } else { UL_WARNING((LOGID, "%!l OnDataChange2(0x%X) FAILED", hr, advmask)); } // UL_WARNING((LOGID, "OnDataChange() 2 Ok")); } if (advmask & loRQ_CONN_DATA_1) { HGLOBAL gmem = 0; unsigned datasize = 0; if (c_datatime) { // UL_DEBUG((LOGID, "OnDataChange1() with time")); if (0 <= lo_OnDataChange1(upl, client_handle, cform_dtime, 1, c_datatime, &gmem, &datasize)) tr++; c_datatime->Release(); } if (c_dataonly) { // UL_DEBUG((LOGID, "OnDataChange1() without time")); if (0 <= lo_OnDataChange1(upl, client_handle, cform_donly, 0, c_dataonly, &gmem, &datasize)) tr++; c_dataonly->Release(); } if (gmem && (// && (!GlobalSize(gmem) ||*/ GlobalFree(gmem))) //(GlobalFlags(gmem) & (GMEM_INVALID_HANDLE | GMEM_DISCARDED)) || GlobalFree(gmem) ) ) { UL_WARNING((LOGID, "%!L GlobalFree(%X) FAILED flags=0x%X", gmem, GlobalFlags(gmem))); } } else if (c_writecomp) { // UL_DEBUG((LOGID, "OnWriteComplete1()")); if (0 <= lo_OnWriteComplete1(upl, client_handle, cform_wrcompl, c_writecomp, 0)) tr++; c_writecomp->Release(); } // UL_DEBUG((LOGID, "send_datachange() finished}")); return tr; }
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; }
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; }