GME  13
MgaCheck.cpp
Go to the documentation of this file.
00001 // MgaCheck.cpp : Implementation of FCO checking operations
00002 #include "stdafx.h"
00003 #include "MgaFCO.h"
00004 
00005 
00006 void setcheck(CMgaProject *mgaproject, CoreObj &ob, int code) {
00007         coreobjhash &list = mgaproject->objstocheck;
00008         coreobjhash::iterator ii;
00009         if((ii = list.find(ob)) != list.end()) (*ii).second |= code;
00010         else list.insert(coreobjhash::value_type(ob, code));
00011 }
00012 
00013 
00014 void docheck(CMgaProject *mgaproject) {
00015         coreobjhash &list = mgaproject->objstocheck;
00016         coreobjhash::iterator i;
00017         
00018         for(i = list.begin(); i != list.end(); ++i) {
00019                 int &mode = (*i).second;
00020                 if(mode & CHK_REFEREES) {
00021                         mode = CHK_REFCONNS;
00022 
00023 //#pragma bookmark todo: put back stuff that needs testing
00024                 }
00025                 if(mode & CHK_REFCONNS) {
00026                         mode = CHK_SELF;
00027                 }
00028 //#pragma bookmark todo: put back stuff that needs testing
00029         }
00030         for(i = list.begin(); i != list.end(); ++i) {
00031                 if (((*i).first).IsDeleted())
00032                         continue;
00033                 if ((*i).second & CHK_ILLEGAL)
00034                 {
00035                         COMTHROW(E_MGA_OP_REFUSED);
00036                 }
00037                 else if((*i).second & CHK_SELF)
00038                 {
00039                         HRESULT hr = ObjForCore((*i).first)->Check();
00040                         if (FAILED(hr))
00041                         {
00042                                 _bstr_t err;
00043                                 if (GetErrorInfo(err.GetAddress()))
00044                                 {
00045                                         throw_com_error(hr, err);
00046                                 }
00047                                 else
00048                                 {
00049                                         COMTHROW(hr);
00050                                 }
00051                         }
00052                 }
00053         }
00054         list.clear();
00055 }
00056 
00057 
00058 
00059 
00060 
00061 
00062 void get_absmetapath(CoreObj &t, CComBSTR &abspath) {
00063         metaref_type mr = t[ATTRID_ROLEMETA];
00064         CoreObj parent = t[ATTRID_FCOPARENT];
00065         if (!parent)
00066                 COMTHROW(E_MGA_OBJECT_DELETED);
00067         if(mr) {
00068                 get_absmetapath(parent, abspath);
00069         }
00070         else mr = t[ATTRID_META];
00071         OLECHAR buf[20];
00072         swprintf(buf, 20, OLESTR(" %ld"), mr);
00073         COMTHROW(abspath.Append(buf));
00074 }
00075 
00076 void get_relmetapath(CoreObj &t, CComBSTR &relpath, CoreObj &pathbeg) {
00077 #ifdef DEBUG
00078         CComBSTR tname = t[ATTRID_NAME], bname = pathbeg[ATTRID_NAME];
00079 #endif
00080         if (COM_EQUAL(t, pathbeg))
00081                 return;
00082         metaref_type mr = t[ATTRID_ROLEMETA];
00083         CoreObj parent = t[ATTRID_FCOPARENT];
00084         if(!mr) {  // == t.IsRootFCO()
00085                 COMTHROW(E_MGA_NOT_CONNECTIBLE);
00086         }
00087         get_relmetapath(parent, relpath, pathbeg);
00088         OLECHAR buf[20];
00089         swprintf(buf, 20, OLESTR(" %ld"), mr);
00090         COMTHROW(relpath.Append(buf));
00091 }
00092 
00093 
00094 
00095 HRESULT FCO::GetAbsMetaPath(BSTR *abspath) {
00096         COMTRY {
00097                 CHECK_OUTSTRPAR(abspath);
00098                 CComBSTR ap;
00099                 ap.Attach(*abspath);
00100                 get_absmetapath(self, ap);              
00101                 *abspath = ap.Detach();
00102         } COMCATCH(;);
00103 }
00104 
00105 HRESULT FCO::GetRelMetaPath(IMgaFCO *begfco, BSTR *rp, IMgaFCOs *refs) {
00106         COMTRY {
00107                 CHECK_OUTSTRPAR(rp);
00108                 CHECK_MYINPTRPAR(begfco);
00109                 CComBSTR relpath;
00110                 relpath.Attach(*rp);
00111                 CoreObj curp(begfco);
00112                 if(refs) {
00113                         MGACOLL_ITERATE(IMgaFCO, refs) {
00114                                 CoreObj r(MGACOLL_ITER);
00115                                 ASSERT(GetMetaID(r) == DTID_REFERENCE);
00116                                 get_relmetapath(r, relpath, curp);
00117                                 curp = r[ATTRID_REFERENCE];
00118                                 ASSERT(curp);
00119                                 {
00120                                         metaref_type mr = curp[ATTRID_META];
00121                                         OLECHAR buf[20];
00122                                         swprintf(buf, 20, OLESTR(" %ld"), mr);
00123                                         COMTHROW(relpath.Append(buf));
00124                                 }
00125                         }
00126                         MGACOLL_ITERATE_END;
00127                 }
00128                 get_relmetapath(self, relpath, curp);           
00129                 *rp = relpath.Detach();
00130         } COMCATCH(;);
00131 }
00132 
00133 
00134 HRESULT FCO::CheckTree() {
00135         COMTRY {
00136                 HRESULT hr = Check();
00137                 if (FAILED(hr))
00138                         return hr;
00139                 objtype_enum typ;
00140                 COMTHROW(get_ObjType(&typ));
00141                 if(typ == OBJTYPE_FOLDER) {
00142                                 ITERATE_THROUGH(self[ATTRID_FCOPARENT+ATTRID_COLLECTION]) {
00143                                         if (FAILED(hr = ObjForCore(ITER)->CheckTree()))
00144                                                 return hr;
00145                                 }
00146                 }
00147                 else {
00148                         CComPtr<IMgaMetaFCO> mfco;
00149                         COMTHROW(get_Meta(&mfco));
00150                         CComPtr<IMgaMetaAttributes> mas;
00151                         COMTHROW(mfco->get_Attributes(&mas));
00152                         ITERATE_THROUGH(self[ATTRID_ATTRPARENT+ATTRID_COLLECTION]) {
00153                                         CComPtr<IMgaMetaAttribute> ma;
00154                                         COMTHROW(mfco->get_AttributeByRef(ITER[ATTRID_META], &ma));
00155                                         if(!ma) COMTHROW(E_MGA_META_VIOLATION);
00156                                         attval_enum vt;
00157                                         COMTHROW(ma->get_ValueType(&vt));
00158                                         int exp = -1;
00159                                         if(vt >= ATTVAL_STRING && vt <= ATTVAL_BOOLEAN) exp = DTID_STRATTR + vt - ATTVAL_STRING;
00160                                         else if(vt == ATTVAL_ENUM || vt == ATTVAL_DYNAMIC) exp = DTID_STRATTR;
00161 
00162                                         if(exp < 0 || exp != ITER.GetMetaID()) COMTHROW(E_MGA_META_VIOLATION);
00163 
00164                                         if(vt == ATTVAL_ENUM) {
00165                                                 CComBSTR val = ITER[ATTRID_STRATTR];
00166                                                 CComPtr<IMgaMetaEnumItems> enumitems;
00167                                                 COMTHROW(ma->get_EnumItems(&enumitems));
00168                                                 MGACOLL_ITERATE(IMgaMetaEnumItem, enumitems) {
00169                                                         CComBSTR eval;
00170                                                         COMTHROW(MGACOLL_ITER->get_Value(&eval));
00171                                                         if(val == eval) break;
00172                                                         
00173                                                 } 
00174                                                 if(MGACOLL_AT_END) COMTHROW(E_META_INVALIDATTR);
00175                                                 MGACOLL_ITERATE_END;
00176                                         }
00177                         }
00178                         if(typ == OBJTYPE_MODEL) {
00179                                 ITERATE_THROUGH(self[ATTRID_FCOPARENT+ATTRID_COLLECTION]) {
00180                                         COMTHROW(ObjForCore(ITER)->CheckTree());
00181                                 }
00182                         }
00183                 }
00184         }
00185         COMCATCH(;);
00186 }
00187 
00188 
00189 HRESULT FCO::Check() {
00190         if(mgaproject->checkofftemporary) return S_OK;
00191         COMTRY {
00192                 objtype_enum typ, parenttyp;
00193                 COMTHROW(get_ObjType(&typ));
00194                 CComPtr<IMgaContainer> parent;
00195                 COMTHROW(GetParent(&parent, &parenttyp));
00196 
00197                 if(typ == OBJTYPE_FOLDER) {
00198                         CComPtr<IMgaMetaFolder> parentmf, metaf;
00199                         COMTHROW(get_MetaFolder(&metaf));
00200                         if (!metaf) {
00201                                 _bstr_t name;
00202                                 this->get_Name(name.GetAddress());
00203                                 metaref_type metaRef = 0;
00204                                 this->get_MetaRef(&metaRef);
00205                                 int iMetaRef = metaRef;
00206                                 wchar_t buf[512];
00207                                 swprintf_s(buf, L"'%s' contains child '%s' with unknown metaref %d", static_cast<const wchar_t*>(parent->Name), static_cast<const wchar_t*>(name), iMetaRef);
00208                                 throw_com_error(E_MGA_META_VIOLATION, buf);
00209                         } else if(!parent) {                                                                                            // root folder
00210                                 CComPtr<IMgaMetaProject> mp;
00211                                 COMTHROW(mgaproject->get_RootMeta(&mp));
00212                                 CComPtr<IMgaMetaFolder> mf;
00213                                 COMTHROW(mp->get_RootFolder(&mf));
00214                                 if(!COM_EQUAL(metaf, mf)) COMTHROW(E_MGA_META_VIOLATION);
00215                         }
00216                         else {                                                                                                          // non-root folder
00217                                 COMTHROW(CComQIPtr<IMgaFolder>(parent)->get_MetaFolder(&parentmf));
00218                             CComPtr<IMgaMetaFolders> fkinds;
00219                             COMTHROW(parentmf->get_LegalChildFolders(&fkinds));
00220                                 MGACOLL_ITERATE(IMgaMetaFolder, fkinds) {
00221                                                 if(COM_EQUAL(metaf, MGACOLL_ITER)) break;
00222                                 }
00223                                 if(MGACOLL_AT_END) {
00224                                         //special case: libroot in rootfolder
00225                                         // (assume this possibility when checkoff is true)
00226                                         CComBSTR libname;
00227                                         bool stillok = false;
00228                                         COMTHROW(get_LibraryName(&libname));
00229                                         if(libname  || 
00230                                                 mgaproject->checkoff || 
00231                                                 self[ATTRID_PERMISSIONS] & EXEMPT_FLAG ) {
00232                                                         objtype_enum t2;
00233                                                         CComPtr<IMgaContainer> p2;
00234                                                         COMTHROW(parent->GetParent( &p2, &t2));
00235                                                         CComBSTR libnm2;
00236                                                         COMTHROW( CComQIPtr<IMgaFolder>(parent)->get_LibraryName( &libnm2));
00237 
00238                                                         // stillok will be turned true if
00239                                                         // parent of library is either another library or the rootfolder
00240                                                         if( t2 == OBJTYPE_NULL) stillok = true;
00241                                                         else if( libnm2)        stillok = true;
00242 
00243                                                         if( !stillok)
00244                                                         {
00245                                                                 // inner libraries need some special care
00246                                                                 // because upon Import XML get_LibraryName gives back 0x0000
00247                                                                 // since the LIBROOT_FLAG, LIBRARY_FLAG flags are not set yet
00248                                                                 CComPtr<IMgaMetaProject> mp;
00249                                                                 COMTHROW(mgaproject->get_RootMeta(&mp));
00250                                                                 CComPtr<IMgaMetaFolder> mf;
00251                                                                 COMTHROW(mp->get_RootFolder(&mf));
00252                                                                 // ok, if current element and its parent are both rootfolders
00253                                                                 stillok = COM_EQUAL( metaf, parentmf) && COM_EQUAL( metaf, mf);
00254                                                         }
00255                                                         if (!stillok)
00256                                                                 COMTHROW(E_MGA_META_VIOLATION);
00257                                         }
00258                                         else
00259                                         {
00260                                                 _bstr_t err = L"'";
00261                                                 err += parentmf->Name + "' cannot contain '" + metaf->Name + L"'";
00262                                                 throw_com_error(E_MGA_META_VIOLATION, err);
00263                                         }
00264                                 }
00265                                 MGACOLL_ITERATE_END;
00266                         }
00267                 }
00268                 else {
00269 #ifdef DEBUG
00270                         CComBSTR bb = self[ATTRID_NAME];
00271 #endif
00272                         CComPtr<IMgaMetaFCO> meta;
00273                         COMTHROW(get_Meta(&meta));
00274         
00275                         CComPtr<IMgaMetaRole> metarole;
00276                         COMTHROW(get_MetaRole( &metarole));
00277                 
00278         
00279                         if (meta == NULL) {
00280                                 _bstr_t name;
00281                                 this->get_Name(name.GetAddress());
00282                                 metaref_type metaRef = 0;
00283                                 this->get_MetaRef(&metaRef);
00284                                 int iMetaRef = metaRef;
00285                                 wchar_t buf[512];
00286                                 swprintf_s(buf, L"'%s' contains child '%s' with unknown metaref %d", static_cast<const wchar_t*>(parent->Name), static_cast<const wchar_t*>(name), iMetaRef);
00287                                 throw_com_error(E_MGA_META_VIOLATION, buf);
00288                         } else if(parenttyp == OBJTYPE_MODEL) {
00289                                 if(!metarole)  COMTHROW(E_MGA_NO_ROLE);
00290                                 CComPtr<IMgaMetaModel> parentmeta1;
00291                                 CComPtr<IMgaMetaFCO> parentmeta2;
00292                                 COMTHROW(metarole->get_ParentModel(&parentmeta1));
00293                                 COMTHROW(CComQIPtr<IMgaModel>(parent)->get_Meta(&parentmeta2));
00294                                 if(!COM_EQUAL(parentmeta1, parentmeta2)) COMTHROW(E_MGA_INVALID_ROLE);
00295         
00296                                 CComPtr<IMgaMetaFCO> kindfromrole;
00297                                 COMTHROW(metarole->get_Kind(&kindfromrole));
00298                                 if(!COM_EQUAL(meta, kindfromrole)) COMTHROW(E_MGA_INVALID_ROLE);
00299                         }
00300                         else if(parenttyp == OBJTYPE_FOLDER) {
00301                                 if(metarole)  COMTHROW(E_MGA_INVALID_ROLE);
00302                                 CComPtr<IMgaMetaFolder> parentmf;
00303                                 COMTHROW(CComQIPtr<IMgaFolder>(parent)->get_MetaFolder(&parentmf));
00304                                 CComPtr<IMgaMetaFCOs> kinds;
00305                                 COMTHROW(parentmf->get_LegalRootObjects(&kinds));
00306                                 MGACOLL_ITERATE(IMgaMetaFCO, kinds) {
00307                                   if(COM_EQUAL(meta, MGACOLL_ITER)) break;
00308                                 }
00309                                 if (MGACOLL_AT_END)
00310                                 {
00311                                         IMgaMetaFCOPtr r = meta.p;
00312                                         _bstr_t err = L"'";
00313                                         err += r->Name + "' cannot be contained in the root folder";
00314                                         throw_com_error(E_MGA_META_VIOLATION, err);
00315                                 }
00316                                 MGACOLL_ITERATE_END;
00317                         }
00318                         else if(parenttyp == OBJTYPE_NULL) {
00319                                 CComPtr<IMgaMetaFolder> mf;
00320                                 CComPtr<IMgaMetaProject> mp;
00321                                 COMTHROW(mgaproject->get_RootMeta(&mp));
00322                                 COMTHROW(mp->get_RootFolder(&mf));
00323                                 if(!COM_EQUAL(mf, meta)) COMTHROW(E_MGA_META_VIOLATION);
00324                         }
00325                         if(typ >= OBJTYPE_REFERENCE && typ <= OBJTYPE_SET) {
00326                                 if(mgaproject->checkoff) {
00327                                         if(mgaproject->deferredchecks.find(this) == mgaproject->deferredchecks.end()) {
00328                                                 mgaproject->deferredchecks.insert(this);
00329                                         }
00330                                 }
00331                                 else
00332                                         CheckRCS();
00333                         }
00334                 }
00335         } COMCATCH(;);
00336 }
00337 
00338 
00339 void FCO::CheckRCS() {
00340         objtype_enum typ;
00341         CComPtr<IMgaMetaFCO> meta;
00342         COMTHROW(get_Meta(&meta));
00343 
00344         COMTHROW(get_ObjType(&typ));
00345         if(typ == OBJTYPE_REFERENCE) {
00346                 CComQIPtr<IMgaMetaReference> refmeta = meta;
00347                 CoreObj target = self[ATTRID_REFERENCE];
00348                 if(target) {
00349                         CComBSTR abspath = "";
00350                         get_absmetapath(target, abspath);
00351                         VARIANT_BOOL good;
00352                         COMTHROW(refmeta->CheckPath(abspath, &good));
00353                         if(!good)
00354                                 COMTHROW(E_MGA_META_VIOLATION);
00355                 }
00356                 // inherited ref can only refer to a derived instance of the target
00357                 // of its base. (Derived null ref is also rejected, but null ref in archetype is accepted)
00358                 CoreObj basetype = self[ATTRID_DERIVED];
00359                 if (basetype && !(mgaproject->preferences & MGAPREF_FREEINSTANCEREFS))
00360                 {
00361                         CoreObj base_target = basetype[ATTRID_REFERENCE];
00362                         if (base_target)
00363                         {
00364                                 for ( ; target; target = target[ATTRID_DERIVED]) {
00365                                         if (COM_EQUAL(base_target, target))
00366                                                 break;
00367                                 }
00368                                 if (!target)
00369                                         COMTHROW(E_MGA_INVALID_TARGET);
00370                         }
00371                 }
00372         }
00373         else if(typ == OBJTYPE_SET) {
00374                 CComQIPtr<IMgaMetaSet> setmeta = meta;
00375                 CComPtr<IMgaFCOs> members;
00376                 COMTHROW(get_Members(&members));
00377                 MGACOLL_ITERATE(IMgaFCO, members) {
00378                         CComBSTR relpath = "";
00379                         get_relmetapath(CoreObj(MGACOLL_ITER), relpath, CoreObj(self[ATTRID_FCOPARENT]));
00380                         VARIANT_BOOL good;
00381                         COMTHROW(setmeta->CheckPath(relpath, &good));
00382                         if(!good)
00383                                 COMTHROW(E_MGA_META_VIOLATION);
00384                 } MGACOLL_ITERATE_END;
00385         }
00386         else if(typ == OBJTYPE_CONNECTION) {
00387                 auto error_gen = [this]() -> _bstr_t {
00388                         IMgaSimpleConnectionPtr simpleConn;
00389                         getinterface(&simpleConn, 0);
00390                         if (!simpleConn)
00391                         {
00392                                 throw;
00393                         }
00394                         _bstr_t err = L"Illegal connection ";
00395                         err += simpleConn->Name;
00396                         err += " (";
00397                         err += simpleConn->Meta->Name;
00398                         err += ")";
00399                         if (simpleConn->Src)
00400                         {
00401                                 err += L" from ";
00402                                 err += simpleConn->Src->Name;
00403                                 err += L" (";
00404                                 err += simpleConn->Src->Meta->Name;
00405                                 err += L") ";
00406                                 if (simpleConn->SrcReferences && simpleConn->SrcReferences->Count > 0)
00407                                 {
00408                                         err += L" through refport ";
00409                                         err += simpleConn->SrcReferences->GetItem(1)->Name;
00410                                         err += "->";
00411                                         IMgaReferencePtr ref = simpleConn->SrcReferences->GetItem(1);
00412                                         err += ref->Referred->Name;
00413                                         err += L" (";
00414                                         err += simpleConn->SrcReferences->GetItem(1)->Meta->Name;
00415                                         err += L")";
00416                                 }
00417                         }
00418                         if (simpleConn->Dst)
00419                         {
00420                                 err += L" to ";
00421                                 err += simpleConn->Dst->Name;
00422                                 err += L" (";
00423                                 err += simpleConn->Dst->Meta->Name;
00424                                 err += L")";
00425                                 if (simpleConn->DstReferences && simpleConn->DstReferences->Count > 0)
00426                                 {
00427                                         err += L" through refport ";
00428                                         err += simpleConn->DstReferences->GetItem(1)->Name;
00429                                         err += "->";
00430                                         IMgaReferencePtr ref = simpleConn->DstReferences->GetItem(1);
00431                                         err += ref->Referred->Name;
00432                                         err += L" (";
00433                                         err += simpleConn->DstReferences->GetItem(1)->Meta->Name;
00434                                         err += L")";
00435                                 }
00436                         }
00437                         return err;
00438                 };
00439                 CComQIPtr<IMgaMetaConnection> connmeta = meta;
00440                 CComBSTR relpath;
00441                 CComBSTR separator = "";
00442                 CoreObjs roles = self[ATTRID_CONNROLE+ATTRID_COLLECTION];
00443                 long c;
00444                 COMTHROW(roles->get_Count(&c));
00445                 if( simpleconn() && 
00446                         !(mgaproject->preferences & MGAPREF_IGNORECONNCHECKS) &&
00447                         c != 2)
00448                 {
00449                         CComBSTR msg;
00450                         msg += "The connection named \"";
00451                         CComBSTR name;
00452                         get_Name(&name);
00453                         msg += name;
00454                         if (c == 0)
00455                                 msg += "\" doesn't have endpoints!";
00456                         else if (c == 1)
00457                                 msg += "\" has only one endpoint!";
00458                         else
00459                                 msg += "\" has more than two endpoints!";
00460                         msg += "\nProperties:\n";
00461                         CComBSTR relpath2;
00462                         CComBSTR separator2 = "";
00463                         COMTRY {
00464                                 ITERATE_THROUGH(roles) {
00465                                         CComBSTR n = ITER[ATTRID_NAME];
00466                                         COMTHROW(relpath2.Append(separator2));
00467                                         COMTHROW(relpath2.Append("Connection role and id: "));
00468                                         COMTHROW(relpath2.Append(n));
00469                                         CoreObj curp(self[ATTRID_FCOPARENT]);
00470                                         CoreObjs segs = ITER[ATTRID_CONNSEG+ATTRID_COLLECTION];
00471                                         segs.Sort();
00472                                         {
00473                                                 ITERATE_THROUGH(segs) {
00474                                                         CoreObj seg = ITER[ATTRID_SEGREF];
00475                                                         ASSERT(seg && GetMetaID(seg) == DTID_REFERENCE);
00476                                                         get_relmetapath(seg, relpath2, curp);
00477                                                         curp = seg[ATTRID_REFERENCE];
00478                                                         if (!curp)
00479                                                                 COMTHROW(E_MGA_META_VIOLATION);;
00480                                                 }
00481                                         }
00482                                         CoreObj end = ITER[ATTRID_XREF];
00483                                         CComPtr<IMgaFCO> endfco;
00484                                         ObjForCore(end)->getinterface(&endfco);
00485                                         get_relmetapath(end, relpath2, curp);
00486                                         COMTHROW(relpath2.Append(", FCO name: "));
00487                                         CComBSTR fcoName;
00488                                         COMTHROW(endfco->get_Name(&fcoName));
00489                                         COMTHROW(relpath2.Append(fcoName));
00490                                         COMTHROW(relpath2.Append(", FCO ID: "));
00491                                         CComBSTR fcoID;
00492                                         COMTHROW(endfco->get_ID(&fcoID));
00493                                         COMTHROW(relpath2.Append(fcoID));
00494                                         separator2 = "\n";
00495                                 }
00496                         }
00497                         catch(hresult_exception &e)
00498                         {
00499                                 throw_com_error(e.hr, error_gen());
00500                         }
00501                         msg += relpath2;
00502                         msg += "\nMissing endpoints sometimes can be generated by UDM based interpreters.";
00503                         throw_com_error(E_MGA_META_VIOLATION, msg);
00504                 }
00505                 try
00506                 {
00507                         ITERATE_THROUGH(roles) {
00508                                 CComBSTR n = ITER[ATTRID_NAME];
00509                                 COMTHROW(relpath.Append(separator));
00510                                 COMTHROW(relpath.Append(n));
00511                                 CoreObj curp(self[ATTRID_FCOPARENT]);
00512                                 CoreObjs segs = ITER[ATTRID_CONNSEG+ATTRID_COLLECTION];
00513                                 segs.Sort();
00514                                 {
00515                                         ITERATE_THROUGH(segs) {
00516                                                 CoreObj seg = ITER[ATTRID_SEGREF];
00517                                                 ASSERT(seg && GetMetaID(seg) == DTID_REFERENCE);
00518                                                 get_relmetapath(seg, relpath, curp);
00519                                                 curp = seg[ATTRID_REFERENCE];
00520                                                 if (!curp)
00521                                                         COMTHROW(E_MGA_META_VIOLATION);;
00522                                         }
00523                                 }
00524                                 CoreObj end = ITER[ATTRID_XREF];
00525                                 CComPtr<IMgaFCO> endfco;
00526                                 ObjForCore(end)->getinterface(&endfco);
00527                                 get_relmetapath(end, relpath, curp);
00528                                 separator = ", ";
00529                         }
00530                 }
00531                 catch (const hresult_exception& e)
00532                 {
00533                         _bstr_t err = error_gen();
00534                         throw_com_error(E_MGA_NOT_CONNECTIBLE, err);
00535                 }
00536                 VARIANT_BOOL good;
00537                 COMTHROW(connmeta->CheckPaths(relpath, &good));
00538                 if (!good)
00539                         throw_com_error(E_MGA_META_VIOLATION, error_gen() + L": meta violation");
00540 
00541         }
00542 }
00543 
00544 
00545 HRESULT FCO::put_Exempt(VARIANT_BOOL newVal) {
00546         COMTRY_IN_TRANSACTION {
00547                 CHECK_INBOOLPAR(newVal);
00548                 if(newVal) {
00549                         self[ATTRID_PERMISSIONS] = self[ATTRID_PERMISSIONS] | EXEMPT_FLAG;
00550                 }
00551                 else {
00552                         self[ATTRID_PERMISSIONS] = self[ATTRID_PERMISSIONS] & ~EXEMPT_FLAG;
00553                         COMTHROW(Check());
00554                 }
00555                 SelfMark(OBJEVENT_PROPERTIES);
00556         } COMCATCH_IN_TRANSACTION(;);
00557 }
00558 
00559 HRESULT FCO::get_Exempt(VARIANT_BOOL *pVal) {
00560         COMTRY {
00561                 CHECK_OUTPAR(pVal);
00562                 *pVal = self[ATTRID_PERMISSIONS] & EXEMPT_FLAG ? VARIANT_TRUE : VARIANT_FALSE; 
00563         } COMCATCH(;);
00564 }
00565 
00566 void change_mode( CoreObj& obj, bool ro)
00567 {
00568         if( ro)
00569         {
00570                 obj[ATTRID_PERMISSIONS] = obj[ATTRID_PERMISSIONS] | READONLY_FLAG;
00571                 CoreObjMark( obj, OBJEVENT_MARKEDRO|OBJEVENT_PROPERTIES);
00572         }
00573         else
00574         {
00575                 obj[ATTRID_PERMISSIONS] = obj[ATTRID_PERMISSIONS] & ~READONLY_FLAG;
00576                 CoreObjMark( obj, OBJEVENT_MARKEDRW|OBJEVENT_PROPERTIES);
00577         }
00578 }
00579 
00580 void change_mode_rec( CoreObj& obj, bool ro)
00581 {
00582         change_mode( obj, ro);
00583 
00584         if( obj.IsContainer())
00585         {
00586                 ITERATE_THROUGH(obj[ATTRID_FCOPARENT+ATTRID_COLLECTION]) 
00587                 {
00588                         change_mode_rec( ITER, ro);
00589                 }
00590         }
00591 }
00592 
00593 HRESULT FCO::PutReadOnlyAccess( VARIANT_BOOL pReadOnly)
00594 {
00595         COMTRY_IN_TRANSACTION {
00596                 CHECK_INBOOLPAR(pReadOnly);
00597 
00598                 change_mode( self, pReadOnly == VARIANT_TRUE);
00599                 COMTHROW(Check());
00600 
00601         } COMCATCH_IN_TRANSACTION(;);
00602 }
00603 
00604 HRESULT FCO::PutReadOnlyAccessWithPropagate( VARIANT_BOOL pReadOnly)
00605 {
00606         COMTRY_IN_TRANSACTION {
00607                 CHECK_INBOOLPAR(pReadOnly);
00608 
00609                 change_mode_rec( self, pReadOnly == VARIANT_TRUE);
00610                 COMTHROW(Check());
00611 
00612         } COMCATCH_IN_TRANSACTION(;);
00613 }
00614 
00615 HRESULT FCO::HasReadOnlyAccess( VARIANT_BOOL *pPtrReadOnly)
00616 {
00617         COMTRY {
00618                 CHECK_OUTPAR(pPtrReadOnly);
00619                 long perm = self[ATTRID_PERMISSIONS];
00620                 *pPtrReadOnly = perm & READONLY_FLAG ? VARIANT_TRUE : VARIANT_FALSE; 
00621         } COMCATCH(;);
00622 }