예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
 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;
   }
예제 #4
0
파일: clidown.cpp 프로젝트: Nerovi/LightOPC
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);
}
예제 #5
0
 STDMETHODIMP LockServer(BOOL fLock)
   {
     UL_DEBUG((LOGID, "myClassFactory::LockServer(%d)", fLock));
     if (fLock) serverAdd();
     else serverRemove();
     return S_OK;
   }
예제 #6
0
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();
   }
}
예제 #7
0
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;
}
예제 #8
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;
}
예제 #9
0
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;
}
예제 #10
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;
}
예제 #11
0
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;
}
예제 #12
0
파일: dopack.cpp 프로젝트: Nerovi/LightOPC
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
파일: dopack.cpp 프로젝트: Nerovi/LightOPC
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;
}