GME  13
MgaRegistrar.cpp
Go to the documentation of this file.
00001 #include "stdafx.h"
00002 #include "MgaRegistrar.h"
00003 #include "atlconv.h"
00004 #include "CommonComponent.h"
00005 #include "Parser.h"
00006 
00007 #import "mscorlib.tlb"
00008 #import "libid:5f45c5d6-4e11-42fc-a558-cfa0b6c7bea6" // MgaDotNetServices
00009 
00010 #include "atlsafe.h"
00011 
00012 #ifdef _DEBUG
00013 void ERRTHROW(LONG err)
00014 {
00015         VERIFYTHROW( err == ERROR_SUCCESS );
00016 }
00017 #else
00018 #define ERRTHROW(FUNC) \
00019 { \
00020         VERIFYTHROW( (FUNC) == ERROR_SUCCESS ); \
00021 }
00022 #endif
00023 
00024 void WIN32THROW(LONG err)
00025 {
00026         if (err != ERROR_SUCCESS)
00027                 HR_THROW(HRESULT_FROM_WIN32(err));
00028 }
00029 
00030 const CString rootreg(_T("SOFTWARE\\GME"));
00031 
00032 
00033 CString QueryValue(CRegKey &key, const TCHAR *name)
00034 {
00035         CString buffer;
00036         TCHAR *bufp = buffer.GetBuffer(4096);
00037         ULONG buflen = 4095;
00038         LONG err = key.QueryStringValue( name, bufp, &buflen);
00039         if( err != ERROR_SUCCESS ) {
00040                 buflen = 0;
00041                 if(err != ERROR_FILE_NOT_FOUND) ERRTHROW(err);
00042         }
00043         ASSERT( 0 <= buflen && buflen < 4096 );
00044         bufp[buflen] = _T('\0');
00045         buffer.ReleaseBuffer();
00046 
00047         return buffer;
00048 }
00049 
00050 // --------------------------- CMgaRegistrar
00051 
00052 #define RM_USER 1 
00053 #define RM_SYS  2
00054 #define RM_SYS2 4
00055 #define RM_BOTH 3
00056 #define RM_TEST 8
00057 #define RM_PRIO          (RM_SYS2 | RM_USER)
00058 #define RM_SYSDOREAD (RM_SYS2 | RM_SYS)
00059 
00060 // For read operations: USER, SYS, PRIO
00061 // For multi-return read operations: USER, SYS, BOTH, PRIO
00062 // For write operations: USER, SYS, BOTH, TEST
00063 
00064 void REVOKE_SYS2(regaccessmode_enum &mode) { *(int *)&mode &= ~RM_SYS2; }
00065 
00066 enum Tristate_t {
00067         Tristate_Enabled,
00068         Tristate_Disabled,
00069         Tristate_Not_Specified,
00070 };
00071 
00072 bool Combine_Tristate(Tristate_t user, Tristate_t system, bool default_ = false) {
00073         if (user != Tristate_Not_Specified) {
00074                 return user == Tristate_Enabled;
00075         }
00076         if (system != Tristate_Not_Specified) {
00077                 return system == Tristate_Enabled;
00078         }
00079         return default_;
00080 }
00081 
00082 Tristate_t IsAssociated_hive(const CString& progidstr, const CString& paradigmstr, HKEY hive) {
00083         CRegKey acomp;
00084 
00085         if (acomp.Open(hive, rootreg + _T("\\Components\\") + progidstr + _T("\\Associated"), KEY_READ) != ERROR_SUCCESS) {
00086                 return Tristate_Not_Specified;
00087         }
00088         ULONG count = 0;
00089         DWORD res = acomp.QueryValue(paradigmstr, NULL, NULL, &count);
00090         if (res != ERROR_SUCCESS) {
00091                 return Tristate_Not_Specified;
00092         }
00093         CString val;
00094         if (acomp.QueryStringValue(paradigmstr, val.GetBufferSetLength(count), &count) == ERROR_SUCCESS) {
00095                 val.ReleaseBuffer();
00096                 if (val == _T("Disabled")) {
00097                         return Tristate_Disabled;
00098                 }
00099         }
00100         return Tristate_Enabled;
00101 }
00102 
00103 bool IsAssociated_regaccess(const CString& progidstr, const CString& paradigmstr, regaccessmode_enum mode) {
00104         if (mode & REGACCESS_BOTH) {
00105                 return  Combine_Tristate(
00106                         IsAssociated_hive(progidstr, paradigmstr, HKEY_CURRENT_USER),
00107                         IsAssociated_hive(progidstr, paradigmstr, HKEY_LOCAL_MACHINE));
00108         } else if (mode & REGACCESS_USER) {
00109                 return IsAssociated_hive(progidstr, paradigmstr, HKEY_CURRENT_USER) == Tristate_Enabled;
00110         } else if (mode & REGACCESS_SYSTEM) {
00111                 return IsAssociated_hive(progidstr, paradigmstr, HKEY_LOCAL_MACHINE) == Tristate_Enabled;
00112         }
00113         return false;
00114 }
00115 
00116 STDMETHODIMP CMgaRegistrar::get_IconPath(regaccessmode_enum mode, BSTR *path)
00117 {
00118         CHECK_OUT(path);
00119 
00120         COMTRY
00121         {
00122                 LONG res;
00123                 CString str;
00124                 if(mode & RM_USER) {
00125                         CRegKey mga;
00126                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00127                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00128                         if(res == ERROR_SUCCESS) {
00129                                 str     = QueryValue(mga, _T("IconPath"));
00130                                 str.TrimRight(_T(" ;,\t"));
00131                                 if(!str.IsEmpty()) REVOKE_SYS2(mode);
00132                         }
00133                 }
00134                 if(mode & (RM_SYSDOREAD)) {
00135                         CRegKey mga;
00136                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00137                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00138                         CString str2;
00139                         if(res == ERROR_SUCCESS) {
00140                                 str2 = QueryValue(mga, _T("IconPath"));
00141                         }
00142                         if (str2 == "") {
00143                                 str2 = "$PARADIGMDIR\\icons;$PROJECTDIR\\icons";
00144                         }
00145                         str2.TrimLeft(_T(" ;,\t"));
00146                         if(!str.IsEmpty() && !str2.IsEmpty())
00147                         {
00148                                 str += _T(";");
00149                                 str     += str2;
00150                         }
00151                         else
00152                                 str = str2;
00153                 }
00154                 CopyTo(str, path);
00155         }
00156         COMCATCH(;)
00157 }
00158 
00159 STDMETHODIMP CMgaRegistrar::put_IconPath(regaccessmode_enum mode, BSTR path)
00160 {
00161         COMTRY
00162         {
00163                 CString str = path;
00164                 if(mode & RM_USER) {
00165                         CRegKey mga;
00166                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00167                         ERRTHROW( mga.SetStringValue( _T("IconPath"), str ));
00168                 }
00169                 if(mode & (RM_SYS | RM_TEST)) {
00170                         CRegKey mga;
00171                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00172                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("IconPath"), str));
00173                 }
00174         }
00175         COMCATCH(;)
00176 }
00177 
00178 STDMETHODIMP CMgaRegistrar::get_ShowMultipleView(regaccessmode_enum mode, VARIANT_BOOL *enabled)
00179 {
00180         COMTRY
00181         {
00182                 LONG res;
00183                 CString str;
00184                 if(mode & RM_USER) {
00185                         CRegKey mga;
00186                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00187                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00188                         if(res == ERROR_SUCCESS) {
00189                                 str     = QueryValue(mga, _T("ShowMultipleView"));
00190                                 if(!str.IsEmpty()) {
00191                                         REVOKE_SYS2(mode);
00192                                 }
00193                         }
00194                 }
00195                 if(mode & (RM_SYSDOREAD)) {
00196                         CRegKey mga;
00197                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00198                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00199                         if(res == ERROR_SUCCESS) {
00200                                 str = QueryValue(mga, _T("ShowMultipleView"));
00201                         }
00202                 }
00203                 *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false
00204         }
00205         COMCATCH(;)
00206 }
00207 
00208 STDMETHODIMP CMgaRegistrar::put_ShowMultipleView(regaccessmode_enum mode, VARIANT_BOOL enabled)
00209 {
00210         COMTRY
00211         {
00212                 CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1");
00213                 if(mode & RM_USER) {
00214                         CRegKey mga;
00215                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00216                         ERRTHROW( mga.SetStringValue( _T("ShowMultipleView"), str));
00217                 }
00218                 if(mode & (RM_SYS | RM_TEST)) {
00219                         CRegKey mga;
00220                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00221                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("ShowMultipleView"), str));
00222                 }
00223         }
00224         COMCATCH(;)
00225 }
00226 
00227 STDMETHODIMP CMgaRegistrar::get_EventLoggingEnabled(regaccessmode_enum mode, VARIANT_BOOL *enabled)
00228 {
00229         COMTRY
00230         {
00231                 LONG res;
00232                 CString str;
00233                 if(mode & RM_USER) {
00234                         CRegKey mga;
00235                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00236                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00237                         if(res == ERROR_SUCCESS) {
00238                                 str     = QueryValue(mga, _T("EventLoggingEnabled"));
00239                                 if(!str.IsEmpty()) {
00240                                         REVOKE_SYS2(mode);
00241                                 }
00242                         }
00243                 }
00244                 if(mode & (RM_SYSDOREAD)) {
00245                         CRegKey mga;
00246                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00247                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00248                         if(res == ERROR_SUCCESS) {
00249                                 str = QueryValue(mga, _T("EventLoggingEnabled"));
00250                         }
00251                 }
00252                 *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false
00253         }
00254         COMCATCH(;)
00255 }
00256 
00257 STDMETHODIMP CMgaRegistrar::put_EventLoggingEnabled(regaccessmode_enum mode, VARIANT_BOOL enabled)
00258 {
00259         COMTRY
00260         {
00261                 CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1");
00262                 if(mode & RM_USER) {
00263                         CRegKey mga;
00264                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00265                         ERRTHROW( mga.SetStringValue( _T("EventLoggingEnabled"), str));
00266                 }
00267                 if(mode & (RM_SYS | RM_TEST)) {
00268                         CRegKey mga;
00269                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00270                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("EventLoggingEnabled"), str));
00271                 }
00272         }
00273         COMCATCH(;)
00274 }
00275 
00276 STDMETHODIMP CMgaRegistrar::get_AutosaveEnabled(regaccessmode_enum mode, VARIANT_BOOL *enabled)
00277 {
00278         COMTRY
00279         {
00280                 LONG res;
00281                 CString str;
00282                 if(mode & RM_USER) {
00283                         CRegKey mga;
00284                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00285                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00286                         if(res == ERROR_SUCCESS) {
00287                                 str     = QueryValue(mga, _T("AutosaveEnabled"));
00288                                 if(!str.IsEmpty()) {
00289                                         REVOKE_SYS2(mode);
00290                                 }
00291                         }
00292                 }
00293                 if(mode & (RM_SYSDOREAD)) {
00294                         CRegKey mga;
00295                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00296                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00297                         if(res == ERROR_SUCCESS) {
00298                                 str = QueryValue(mga, _T("AutosaveEnabled"));
00299                         }
00300                 }
00301                 *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false
00302         }
00303         COMCATCH(;)
00304 }
00305 
00306 STDMETHODIMP CMgaRegistrar::put_AutosaveEnabled(regaccessmode_enum mode, VARIANT_BOOL enabled)
00307 {
00308         COMTRY
00309         {
00310                 CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1");
00311                 if(mode & RM_USER) {
00312                         CRegKey mga;
00313                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00314                         ERRTHROW( mga.SetStringValue( _T("AutosaveEnabled"), str));
00315                 }
00316                 if(mode & (RM_SYS | RM_TEST)) {
00317                         CRegKey mga;
00318                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00319                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("AutosaveEnabled"), str));
00320                 }
00321         }
00322         COMCATCH(;)
00323 }
00324 
00325 STDMETHODIMP CMgaRegistrar::get_AutosaveFreq(regaccessmode_enum mode, long *secs)
00326 {
00327         COMTRY
00328         {
00329                 LONG res;
00330                 CString str;
00331                 if(mode & RM_USER) {
00332                         CRegKey mga;
00333                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00334                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00335                         if(res == ERROR_SUCCESS) {
00336                                 str     = QueryValue(mga, _T("AutosaveFreq"));
00337                                 if(!str.IsEmpty()) {
00338                                         REVOKE_SYS2(mode);
00339                                 }
00340                         }
00341                 }
00342                 if(mode & (RM_SYSDOREAD)) {
00343                         CRegKey mga;
00344                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00345                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00346                         if(res == ERROR_SUCCESS) {
00347                                 str = QueryValue(mga, _T("AutosaveFreq"));
00348                         }
00349                 }
00350                 if (_stscanf((LPCTSTR)str, _T("%ld"), secs) != 1) {
00351                         *secs = 60;     // Default value: 1 minute
00352                 }
00353         }
00354         COMCATCH(;)
00355 }
00356 
00357 STDMETHODIMP CMgaRegistrar::put_AutosaveFreq(regaccessmode_enum mode, long secs)
00358 {
00359         COMTRY
00360         {
00361                 CString str;
00362                 str.Format(_T("%ld"), secs);
00363                 if(mode & RM_USER) {
00364                         CRegKey mga;
00365                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00366                         ERRTHROW( mga.SetStringValue( _T("AutosaveFreq"), str));
00367                 }
00368                 if(mode & (RM_SYS | RM_TEST)) {
00369                         CRegKey mga;
00370                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00371                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("AutosaveFreq"), str));
00372                 }
00373         }
00374         COMCATCH(;)
00375 }
00376 
00377 STDMETHODIMP CMgaRegistrar::get_AutosaveUseDir(regaccessmode_enum mode, VARIANT_BOOL *enabled)
00378 {
00379         COMTRY
00380         {
00381                 LONG res;
00382                 CString str;
00383                 if(mode & RM_USER) {
00384                         CRegKey mga;
00385                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00386                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00387                         if(res == ERROR_SUCCESS) {
00388                                 str     = QueryValue(mga, _T("AutosaveUseDir"));
00389                                 if(!str.IsEmpty()) {
00390                                         REVOKE_SYS2(mode);
00391                                 }
00392                         }
00393                 }
00394                 if(mode & (RM_SYSDOREAD)) {
00395                         CRegKey mga;
00396                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00397                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00398                         if(res == ERROR_SUCCESS) {
00399                                 str = QueryValue(mga, _T("AutosaveUseDir"));
00400                         }
00401                 }
00402                 *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false
00403         }
00404         COMCATCH(;)
00405 }
00406 
00407 STDMETHODIMP CMgaRegistrar::put_AutosaveUseDir(regaccessmode_enum mode, VARIANT_BOOL enabled)
00408 {
00409         COMTRY
00410         {
00411                 CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1");
00412                 if(mode & RM_USER) {
00413                         CRegKey mga;
00414                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00415                         ERRTHROW( mga.SetStringValue( _T("AutosaveUseDir"), str));
00416                 }
00417                 if(mode & (RM_SYS | RM_TEST)) {
00418                         CRegKey mga;
00419                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00420                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("AutosaveUseDir"), str));
00421                 }
00422         }
00423         COMCATCH(;)
00424 }
00425 
00426 STDMETHODIMP CMgaRegistrar::get_AutosaveDir(regaccessmode_enum mode, BSTR *dir)
00427 {
00428         CHECK_OUT(dir);
00429 
00430         COMTRY
00431         {
00432                 LONG res;
00433                 CString str;
00434                 if(mode & RM_USER) {
00435                         CRegKey mga;
00436                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00437                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00438                         if(res == ERROR_SUCCESS) {
00439                                 str     = QueryValue(mga, _T("AutosaveDir"));
00440                         }
00441                 }
00442                 if(mode & (RM_SYSDOREAD)) {
00443                         CRegKey mga;
00444                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00445                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00446                         if(res == ERROR_SUCCESS) {
00447                                 str = QueryValue(mga, _T("AutosaveDir"));
00448                         }
00449                 }
00450                 CopyTo(str, dir);
00451         }
00452         COMCATCH(;)
00453 }
00454 
00455 STDMETHODIMP CMgaRegistrar::put_AutosaveDir(regaccessmode_enum mode, BSTR dir)
00456 {
00457         COMTRY
00458         {
00459                 CString str = dir;
00460                 if(mode & RM_USER) {
00461                         CRegKey mga;
00462                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00463                         ERRTHROW( mga.SetStringValue( _T("AutosaveDir"), str));
00464                 }
00465                 if(mode & (RM_SYS | RM_TEST)) {
00466                         CRegKey mga;
00467                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00468                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("AutosaveDir"), str));
00469                 }
00470         }
00471         COMCATCH(;)
00472 }
00473 
00474 
00475 STDMETHODIMP CMgaRegistrar::get_ExternalEditorEnabled(regaccessmode_enum mode, VARIANT_BOOL *enabled)
00476 {
00477         COMTRY
00478         {
00479                 LONG res;
00480                 CString str;
00481                 if(mode & RM_USER) {
00482                         CRegKey mga;
00483                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00484                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00485                         if(res == ERROR_SUCCESS) {
00486                                 str     = QueryValue(mga, _T("ExternalEditorEnabled"));
00487                                 if(!str.IsEmpty()) {
00488                                         REVOKE_SYS2(mode);
00489                                 }
00490                         }
00491                 }
00492                 if(mode & (RM_SYSDOREAD)) {
00493                         CRegKey mga;
00494                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00495                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00496                         if(res == ERROR_SUCCESS) {
00497                                 str = QueryValue(mga, _T("ExternalEditorEnabled"));
00498                         }
00499                 }
00500                 *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false
00501         }
00502         COMCATCH(;)
00503 }
00504 
00505 STDMETHODIMP CMgaRegistrar::put_ExternalEditorEnabled(regaccessmode_enum mode, VARIANT_BOOL enabled)
00506 {
00507         COMTRY
00508         {
00509                 CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1");
00510                 if(mode & RM_USER) {
00511                         CRegKey mga;
00512                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00513                         ERRTHROW( mga.SetStringValue( _T("ExternalEditorEnabled"), str));
00514                 }
00515                 if(mode & (RM_SYS | RM_TEST)) {
00516                         CRegKey mga;
00517                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00518                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("ExternalEditorEnabled"), str));
00519                 }
00520         }
00521         COMCATCH(;)
00522 }
00523 
00524 STDMETHODIMP CMgaRegistrar::get_ExternalEditor(regaccessmode_enum mode, BSTR *path)
00525 {
00526         CHECK_OUT(path);
00527 
00528         COMTRY
00529         {
00530                 LONG res;
00531                 CString str;
00532                 if(mode & RM_USER) {
00533                         CRegKey mga;
00534                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00535                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00536                         if(res == ERROR_SUCCESS) {
00537                                 str     = QueryValue(mga, _T("ExternalEditor"));
00538                         }
00539                 }
00540                 if(mode & (RM_SYSDOREAD)) {
00541                         CRegKey mga;
00542                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00543                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00544                         if(res == ERROR_SUCCESS) {
00545                                 str = QueryValue(mga, _T("ExternalEditor"));
00546                         }
00547                 }
00548                 CopyTo(str, path);
00549         }
00550         COMCATCH(;)
00551 }
00552 
00553 STDMETHODIMP CMgaRegistrar::put_ExternalEditor(regaccessmode_enum mode, BSTR path)
00554 {
00555         COMTRY
00556         {
00557                 CString str = path;
00558                 if(mode & RM_USER) {
00559                         CRegKey mga;
00560                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00561                         ERRTHROW( mga.SetStringValue( _T("ExternalEditor"), str));
00562                 }
00563                 if(mode & (RM_SYS | RM_TEST)) {
00564                         CRegKey mga;
00565                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00566                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("ExternalEditor"), str));
00567                 }
00568         }
00569         COMCATCH(;)
00570 }
00571 
00572 
00573 STDMETHODIMP CMgaRegistrar::get_UseAutoRouting(regaccessmode_enum mode, VARIANT_BOOL *enabled)
00574 {
00575         COMTRY
00576         {
00577                 LONG res;
00578                 CString str;
00579                 if(mode & RM_USER) {
00580                         CRegKey mga;
00581                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00582                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00583                         if(res == ERROR_SUCCESS) {
00584                                 str     = QueryValue(mga, _T("UseAutoRouting"));
00585                                 if(!str.IsEmpty()) {
00586                                         REVOKE_SYS2(mode);
00587                                 }
00588                         }
00589                 }
00590                 if(mode & (RM_SYSDOREAD)) {
00591                         CRegKey mga;
00592                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00593                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00594                         if(res == ERROR_SUCCESS) {
00595                                 str = QueryValue(mga, _T("UseAutoRouting"));
00596                         }
00597                 }
00598                 *enabled = (str == _T("0")) ? VARIANT_FALSE : VARIANT_TRUE; // Default value: true
00599         }
00600         COMCATCH(;)
00601 }
00602 
00603 
00604 STDMETHODIMP CMgaRegistrar::put_UseAutoRouting(regaccessmode_enum mode, VARIANT_BOOL enabled)
00605 {
00606         COMTRY
00607         {
00608                 CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1");
00609                 if(mode & RM_USER) {
00610                         CRegKey mga;
00611                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00612                         ERRTHROW( mga.SetStringValue( _T("UseAutoRouting"), str));
00613                 }
00614                 if(mode & (RM_SYS | RM_TEST)) {
00615                         CRegKey mga;
00616                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00617                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("UseAutoRouting"), str));
00618                 }
00619         }
00620         COMCATCH(;)
00621 }
00622 
00623 
00624 STDMETHODIMP CMgaRegistrar::get_LabelAvoidance(regaccessmode_enum mode, VARIANT_BOOL *enabled)
00625 {
00626         COMTRY
00627         {
00628                 LONG res;
00629                 CString str;
00630                 if(mode & RM_USER) {
00631                         CRegKey mga;
00632                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00633                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00634                         if(res == ERROR_SUCCESS) {
00635                                 str     = QueryValue(mga, _T("LabelAvoidance"));
00636                                 if(!str.IsEmpty()) {
00637                                         REVOKE_SYS2(mode);
00638                                 }
00639                         }
00640                 }
00641                 if(mode & (RM_SYSDOREAD)) {
00642                         CRegKey mga;
00643                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00644                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00645                         if(res == ERROR_SUCCESS) {
00646                                 str = QueryValue(mga, _T("LabelAvoidance"));
00647                         }
00648                 }
00649                 *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false
00650         }
00651         COMCATCH(;)
00652 }
00653 
00654 
00655 STDMETHODIMP CMgaRegistrar::put_LabelAvoidance(regaccessmode_enum mode, VARIANT_BOOL enabled)
00656 {
00657         COMTRY
00658         {
00659                 CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1");
00660                 if(mode & RM_USER) {
00661                         CRegKey mga;
00662                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00663                         ERRTHROW( mga.SetStringValue( _T("LabelAvoidance"), str));
00664                 }
00665                 if(mode & (RM_SYS | RM_TEST)) {
00666                         CRegKey mga;
00667                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00668                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("LabelAvoidance"), str));
00669                 }
00670         }
00671         COMCATCH(;)
00672 }
00673 
00674 STDMETHODIMP CMgaRegistrar::get_ScriptEngine(regaccessmode_enum mode, BSTR *path) {
00675         CHECK_OUT(path);
00676 
00677         COMTRY
00678         {
00679                 LONG res;
00680                 CString str;
00681                 if(mode & RM_USER) {
00682                         CRegKey mga;
00683                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00684                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00685                         if(res == ERROR_SUCCESS) {
00686                                 str     = QueryValue(mga, _T("ScriptEngine"));
00687                                 str.TrimRight(_T(" ;,\t"));
00688                                 if(!str.IsEmpty()) REVOKE_SYS2(mode);
00689                         }
00690                 }
00691                 if(mode & (RM_SYSDOREAD)) {
00692                         CRegKey mga;
00693                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00694                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00695                         if(res == ERROR_SUCCESS) {
00696                                 CString str2 = QueryValue(mga, _T("ScriptEngine"));
00697                                 str2.TrimLeft(_T(" ;,\t"));
00698                                 if(!str.IsEmpty() && !str2.IsEmpty()) str += _T(";");
00699                                 str     += str2;
00700                         }
00701                 }
00702                 CopyTo(str, path);
00703         }
00704         COMCATCH(;)
00705 }
00706 
00707 STDMETHODIMP CMgaRegistrar::put_ScriptEngine(regaccessmode_enum mode, BSTR path) {
00708         COMTRY
00709         {
00710                 CString str = path;
00711                 if(mode & RM_USER) {
00712                         CRegKey mga;
00713                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00714                         ERRTHROW( mga.SetStringValue(_T("ScriptEngine"), str) );//z7
00715                 }
00716                 if(mode & (RM_SYS | RM_TEST)) {
00717                         CRegKey mga;
00718                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00719                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue(_T("ScriptEngine"), str) );//z7
00720                 }
00721         }
00722         COMCATCH(;)
00723 }
00724 
00725 STDMETHODIMP CMgaRegistrar::GetDefZoomLevel(regaccessmode_enum p_mode, BSTR *p_zlev)
00726 {
00727         CHECK_OUT(p_zlev);
00728         COMTRY
00729         {
00730                 LONG res;
00731                 CString str;
00732                 if(p_mode & RM_USER) {
00733                         CRegKey mga;
00734                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00735                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00736                         if(res == ERROR_SUCCESS) {
00737                                 str     = QueryValue(mga, _T("DefaultZoomLevel"));
00738                                 if(!str.IsEmpty()) REVOKE_SYS2(p_mode);
00739                         }
00740                 }
00741                 if(p_mode & (RM_SYSDOREAD)) {
00742                         CRegKey mga;
00743                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00744                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00745                         if(res == ERROR_SUCCESS) {
00746                                 str = QueryValue(mga, _T("DefaultZoomLevel"));
00747                         }
00748                 }
00749                 CopyTo(str, p_zlev);
00750         }
00751         COMCATCH(;)
00752 
00753 }
00754 
00755 STDMETHODIMP CMgaRegistrar::SetDefZoomLevel(regaccessmode_enum p_mode, BSTR p_zlev)
00756 {
00757         COMTRY
00758         {
00759                 CString str = p_zlev;
00760                 if(p_mode & RM_USER) {
00761                         CRegKey mga;
00762                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00763                         ERRTHROW( mga.SetStringValue( _T("DefaultZoomLevel"), str));
00764                 }
00765                 if(p_mode & (RM_SYS | RM_TEST)) {
00766                         CRegKey mga;
00767                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00768                         if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("DefaultZoomLevel"), str));
00769                 }
00770         }
00771         COMCATCH(;)
00772 }
00773 
00774 
00775 STDMETHODIMP CMgaRegistrar::GetMouseOverNotify(regaccessmode_enum mode, VARIANT_BOOL *enabled)
00776 {
00777         COMTRY
00778         {
00779                 LONG res;
00780                 CString str;
00781                 if(mode & RM_USER) {
00782                         CRegKey mga;
00783                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00784                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00785                         if(res == ERROR_SUCCESS) {
00786                                 str     = QueryValue(mga, _T("MouseOverNotify"));
00787                                 if(!str.IsEmpty()) {
00788                                         REVOKE_SYS2(mode);
00789                                 }
00790                         }
00791                 }
00792                 if(mode & (RM_SYSDOREAD)) {
00793                         CRegKey mga;
00794                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00795                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00796                         if(res == ERROR_SUCCESS) {
00797                                 str = QueryValue(mga, _T("MouseOverNotify"));
00798                         }
00799                 }
00800                 *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false
00801         }
00802         COMCATCH(;)
00803 }
00804 
00805 
00806 STDMETHODIMP CMgaRegistrar::SetMouseOverNotify(regaccessmode_enum mode, VARIANT_BOOL enabled)
00807 {
00808         COMTRY
00809         {
00810                 CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1");
00811                 if(mode & RM_USER) {
00812                         CRegKey mga;
00813                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00814                         ERRTHROW( mga.SetStringValue( _T("MouseOverNotify"), str));
00815                 }
00816                 if(mode & (RM_SYS | RM_TEST)) {
00817                         CRegKey mga;
00818                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00819                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("MouseOverNotify"), str));
00820                 }
00821         }
00822         COMCATCH(;)
00823 }
00824 
00825 STDMETHODIMP CMgaRegistrar::GetRealNmbFmtStr(regaccessmode_enum p_mode, BSTR *p_fmtStr)
00826 {
00827         CHECK_OUT(p_fmtStr);
00828         COMTRY
00829         {
00830                 LONG res;
00831                 CString str;
00832                 if(p_mode & RM_USER) {
00833                         CRegKey mga;
00834                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00835                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00836                         if(res == ERROR_SUCCESS) {
00837                                 str     = QueryValue(mga, _T("RealNmbFmtStr"));
00838                                 if(!str.IsEmpty()) REVOKE_SYS2(p_mode);
00839                         }
00840                 }
00841                 if(p_mode & (RM_SYSDOREAD)) {
00842                         CRegKey mga;
00843                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00844                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00845                         if(res == ERROR_SUCCESS) {
00846                                 str = QueryValue(mga, _T("RealNmbFmtStr"));
00847                         }
00848                 }
00849                 CopyTo(str, p_fmtStr);
00850         }
00851         COMCATCH(;)
00852 
00853 }
00854 
00855 STDMETHODIMP CMgaRegistrar::SetRealNmbFmtStr(regaccessmode_enum p_mode, BSTR p_fmtStr)
00856 {
00857         COMTRY
00858         {
00859                 CString str = p_fmtStr;
00860                 if(p_mode & RM_USER) {
00861                         CRegKey mga;
00862                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00863                         ERRTHROW( mga.SetStringValue( _T("RealNmbFmtStr"), str));
00864                 }
00865                 if(p_mode & (RM_SYS | RM_TEST)) {
00866                         CRegKey mga;
00867                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00868                         if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("RealNmbFmtStr"), str));
00869                 }
00870         }
00871         COMCATCH(;)
00872 }
00873 
00874 STDMETHODIMP CMgaRegistrar::GetTimeStamping(regaccessmode_enum p_mode, VARIANT_BOOL *p_enabled)
00875 {
00876         COMTRY
00877         {
00878                 LONG res;
00879                 CString str;
00880                 if(p_mode & RM_USER) {
00881                         CRegKey mga;
00882                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00883                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00884                         if(res == ERROR_SUCCESS) {
00885                                 str     = QueryValue(mga, _T("TimeStamping"));
00886                                 if(!str.IsEmpty()) {
00887                                         REVOKE_SYS2(p_mode);
00888                                 }
00889                         }
00890                 }
00891                 if(p_mode & (RM_SYSDOREAD)) {
00892                         CRegKey mga;
00893                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00894                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00895                         if(res == ERROR_SUCCESS) {
00896                                 str = QueryValue(mga, _T("TimeStamping"));
00897                         }
00898                 }
00899                 *p_enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false
00900         }
00901         COMCATCH(;)
00902 }
00903 
00904 STDMETHODIMP CMgaRegistrar::SetTimeStamping(regaccessmode_enum p_mode, VARIANT_BOOL p_enabled)
00905 {
00906         COMTRY
00907         {
00908                 CString str = (p_enabled == VARIANT_FALSE) ? _T("0") : _T("1");
00909                 if(p_mode & RM_USER) {
00910                         CRegKey mga;
00911                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00912                         ERRTHROW( mga.SetStringValue( _T("TimeStamping"), str));
00913                 }
00914                 if(p_mode & (RM_SYS | RM_TEST)) {
00915                         CRegKey mga;
00916                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00917                         if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("TimeStamping"), str));
00918                 }
00919         }
00920         COMCATCH(;)
00921 }
00922 
00923 STDMETHODIMP CMgaRegistrar::GetNavigation(regaccessmode_enum p_mode, VARIANT_BOOL *p_enabled)
00924 {
00925         COMTRY
00926         {
00927                 LONG res;
00928                 CString str;
00929                 if(p_mode & RM_USER) {
00930                         CRegKey mga;
00931                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00932                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00933                         if(res == ERROR_SUCCESS) {
00934                                 str     = QueryValue(mga, _T("Navigation"));
00935                                 if(!str.IsEmpty()) {
00936                                         REVOKE_SYS2(p_mode);
00937                                 }
00938                         }
00939                 }
00940                 if(p_mode & (RM_SYSDOREAD)) {
00941                         CRegKey mga;
00942                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00943                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00944                         if(res == ERROR_SUCCESS) {
00945                                 str = QueryValue(mga, _T("Navigation"));
00946                         }
00947                 }
00948                 *p_enabled = (str == _T("0")) ? VARIANT_FALSE : VARIANT_TRUE; // Default value: true
00949         }
00950         COMCATCH(;)
00951 }
00952 
00953 STDMETHODIMP CMgaRegistrar::SetNavigation(regaccessmode_enum p_mode, VARIANT_BOOL p_enabled)
00954 {
00955         COMTRY
00956         {
00957                 CString str = (p_enabled == VARIANT_FALSE) ? _T("0") : _T("1");
00958                 if(p_mode & RM_USER) {
00959                         CRegKey mga;
00960                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
00961                         ERRTHROW( mga.SetStringValue( _T("Navigation"), str));
00962                 }
00963                 if(p_mode & (RM_SYS | RM_TEST)) {
00964                         CRegKey mga;
00965                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
00966                         if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("Navigation"), str));
00967                 }
00968         }
00969         COMCATCH(;)
00970 }
00971 
00972 STDMETHODIMP CMgaRegistrar::GetUndoQueueSize(regaccessmode_enum p_mode, BSTR *p_qusz)
00973 {
00974         CHECK_OUT(p_qusz);
00975         COMTRY
00976         {
00977                 LONG res;
00978                 CString str;
00979                 if(p_mode & RM_USER) {
00980                         CRegKey mga;
00981                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
00982                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00983                         if(res == ERROR_SUCCESS) {
00984                                 str     = QueryValue(mga, _T("UndoQueueSize"));
00985                                 if(!str.IsEmpty()) REVOKE_SYS2(p_mode);
00986                         }
00987                 }
00988                 if(p_mode & (RM_SYSDOREAD)) {
00989                         CRegKey mga;
00990                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
00991                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
00992                         if(res == ERROR_SUCCESS) {
00993                                 str = QueryValue(mga, _T("UndoQueueSize"));
00994                         }
00995                 }
00996                 CopyTo(str, p_qusz);
00997         }
00998         COMCATCH(;)
00999 
01000 }
01001 
01002 STDMETHODIMP CMgaRegistrar::SetUndoQueueSize(regaccessmode_enum p_mode, BSTR p_qusz)
01003 {
01004         COMTRY
01005         {
01006                 CString str = p_qusz;
01007                 if(p_mode & RM_USER) {
01008                         CRegKey mga;
01009                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
01010                         ERRTHROW( mga.SetStringValue( _T("UndoQueueSize"), str));
01011                 }
01012                 if(p_mode & (RM_SYS | RM_TEST)) {
01013                         CRegKey mga;
01014                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
01015                         if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("UndoQueueSize"), str));
01016                 }
01017         }
01018         COMCATCH(;)
01019 }
01020 
01021 STDMETHODIMP CMgaRegistrar::get_EdgeSmoothMode(regaccessmode_enum mode, edgesmoothmode_enum* smoothMode)
01022 {
01023         COMTRY
01024         {
01025                 LONG res;
01026                 CString str;
01027                 if(mode & RM_USER) {
01028                         CRegKey mga;
01029                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
01030                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01031                         if(res == ERROR_SUCCESS) {
01032                                 str     = QueryValue(mga, _T("EdgeSmoothMode"));
01033                                 if(!str.IsEmpty()) {
01034                                         REVOKE_SYS2(mode);
01035                                 }
01036                         }
01037                 }
01038                 if(mode & (RM_SYSDOREAD)) {
01039                         CRegKey mga;
01040                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
01041                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01042                         if(res == ERROR_SUCCESS) {
01043                                 str = QueryValue(mga, _T("EdgeSmoothMode"));
01044                         }
01045                 }
01046                 *smoothMode = (edgesmoothmode_enum)(str.IsEmpty() ? 2 : _tcstol(str, NULL, 10));
01047         }
01048         COMCATCH(;)
01049 }
01050 
01051 STDMETHODIMP CMgaRegistrar::put_EdgeSmoothMode(regaccessmode_enum mode, edgesmoothmode_enum smoothMode)
01052 {
01053         COMTRY
01054         {
01055                 CString str;
01056                 str.Format(_T("%d"), smoothMode);
01057                 if(mode & RM_USER) {
01058                         CRegKey mga;
01059                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
01060                         ERRTHROW( mga.SetStringValue( _T("EdgeSmoothMode"), str));
01061                 }
01062                 if(mode & (RM_SYS | RM_TEST)) {
01063                         CRegKey mga;
01064                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
01065                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("EdgeSmoothMode"), str));
01066                 }
01067         }
01068         COMCATCH(;)
01069 }
01070 
01071 STDMETHODIMP CMgaRegistrar::get_FontSmoothMode(regaccessmode_enum mode, fontsmoothmode_enum* smoothMode)
01072 {
01073         COMTRY
01074         {
01075                 LONG res;
01076                 CString str;
01077                 if(mode & RM_USER) {
01078                         CRegKey mga;
01079                         res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ);
01080                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01081                         if(res == ERROR_SUCCESS) {
01082                                 str     = QueryValue(mga, _T("FontSmoothMode"));
01083                                 if(!str.IsEmpty()) {
01084                                         REVOKE_SYS2(mode);
01085                                 }
01086                         }
01087                 }
01088                 if(mode & (RM_SYSDOREAD)) {
01089                         CRegKey mga;
01090                         res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ);
01091                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01092                         if(res == ERROR_SUCCESS) {
01093                                 str = QueryValue(mga, _T("FontSmoothMode"));
01094                         }
01095                 }
01096                 *smoothMode = (fontsmoothmode_enum)(str.IsEmpty() ? 4 : _tcstol(str, NULL, 10));
01097         }
01098         COMCATCH(;)
01099 }
01100 
01101 STDMETHODIMP CMgaRegistrar::put_FontSmoothMode(regaccessmode_enum mode, fontsmoothmode_enum smoothMode)
01102 {
01103         COMTRY
01104         {
01105                 CString str;
01106                 str.Format(_T("%d"), smoothMode);
01107                 if(mode & RM_USER) {
01108                         CRegKey mga;
01109                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
01110                         ERRTHROW( mga.SetStringValue( _T("FontSmoothMode"), str));
01111                 }
01112                 if(mode & (RM_SYS | RM_TEST)) {
01113                         CRegKey mga;
01114                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
01115                         if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("FontSmoothMode"), str));
01116                 }
01117         }
01118         COMCATCH(;)
01119 }
01120 
01121 STDMETHODIMP CMgaRegistrar::get_Paradigms(regaccessmode_enum mode, VARIANT *names)
01122 {
01123         CHECK_OUT(names);
01124 
01125         COMTRY
01126         {
01127                 CStringArray ret;
01128                 if(mode & RM_USER) {
01129                         CRegKey pars;
01130                         LONG res = pars.Open(HKEY_CURRENT_USER, rootreg+_T("\\Paradigms"), KEY_READ);
01131                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01132                         if(res == ERROR_SUCCESS) {
01133                                 for(int index = 0;; ++index) {
01134                                         TCHAR name[1024];
01135                                         LONG err = RegEnumKey(pars, index, name, 1024);
01136                                         if( err == ERROR_NO_MORE_ITEMS )
01137                                                 break;
01138                                         ERRTHROW( err );
01139 
01140                                         REVOKE_SYS2(mode);
01141                                         ret.Add(name);
01142                                 }
01143 
01144                         }
01145                 }
01146                 int retlen = ret.GetSize();
01147 
01148                 if(mode & RM_SYSDOREAD) {
01149                         CRegKey pars;
01150                         LONG res = pars.Open(HKEY_LOCAL_MACHINE, rootreg+_T("\\Paradigms"), KEY_READ | KEY_WOW64_32KEY);
01151                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01152                         if(res == ERROR_SUCCESS) {
01153                                 for(int index = 0;; ++index) {
01154                                         TCHAR name[1024];
01155                                         LONG err = RegEnumKey(pars, index, name, 1024);
01156                                         if( err == ERROR_NO_MORE_ITEMS )
01157                                                 break;
01158                                         ERRTHROW( err );
01159                                         int j;
01160                                         for(j = 0; j < retlen; j++) {           // Make sure, name is not present already, if yes, system copy is ignored
01161                                                 if(!ret[j].CompareNoCase(name)) break;
01162                                         }
01163                                         if(j != retlen) continue;
01164                                         ret.Add(name);
01165                                 }
01166 
01167                         }
01168                 }
01169 
01170 
01171                 CopyTo(ret, names);
01172         }
01173         COMCATCH(;)
01174 }
01175 
01176 
01177 HRESULT GetMtaInfo(BSTR conn, BSTR *parname, BSTR *version, VARIANT *guid) {
01178         COMTRY {
01179                 CComObjPtr<IMgaMetaProject> paradigm;
01180                 COMTHROW( paradigm.CoCreateInstance(OLESTR("MGA.MgaMetaProject")) );
01181                 ASSERT( paradigm != NULL );
01182 
01183                 COMTHROW( paradigm->Open(conn) );
01184 
01185                 COMTHROW( paradigm->get_Name(parname) );
01186 
01187                 COMTHROW( paradigm->get_Version(version) );
01188 
01189                 COMTHROW( paradigm->get_GUID(guid) );
01190 
01191                 COMTHROW( paradigm->Close() );
01192         } COMCATCH(;)
01193 }
01194 
01195 STDMETHODIMP CMgaRegistrar::RegisterParadigmFromDataDisp(BSTR connstr, regaccessmode_enum mode, BSTR *newname)
01196 {
01197         return RegisterParadigmFromData( connstr, newname, mode);
01198 }
01199 
01200 STDMETHODIMP CMgaRegistrar::RegisterParadigmFromData(BSTR connstr, BSTR *newname, regaccessmode_enum mode)
01201 {
01202         CHECK_IN(connstr);
01203         if(newname) CHECK_OUT(newname);
01204         COMTRY {
01205                 CString conn = connstr;
01206                 CString connrecent;
01207                 // we have to parse it
01208                 if( conn.Left(4) == _T("XML=") )
01209                 {
01210                         CString file = conn.Mid(4);
01211 
01212                         conn = _T("MGA=");
01213                         conn += file;
01214 
01215                         if( conn.Right(4).CompareNoCase(_T(".xml")) == 0 || 
01216                                 conn.Right(4).CompareNoCase(_T(".xmp")) == 0 ) {
01217                                 conn.Delete(conn.GetLength() - 4, 4);
01218                         }
01219                         conn += _T(".mta");
01220 #define FILEPART(x) (((LPCTSTR)x)+4)
01221                         DWORD info = GetFileAttributes(FILEPART(conn));
01222                         if(info != 0xFFFFFFFF ) {       // save old version of paradigm under another name
01223                           if(info & FILE_ATTRIBUTE_DIRECTORY) COMTHROW(E_FILEOPEN);
01224                           try {
01225                                 CComBstrObj name;       // Format: name-<GUID>
01226                                 CComVariant prevguid;
01227                                 CComBstrObj prevversion;
01228                                 COMTHROW(GetMtaInfo(PutInBstr(conn), PutOut(name), PutOut(prevversion), PutOut(prevguid)));
01229                                 CComBstrObj conn1;
01230                                 if(QueryParadigm(name, PutOut(conn1), &prevguid, REGACCESS_PRIORITY) == S_OK &&
01231                                         conn1 == CComBSTR(conn)) {  // if it was correctly registered under the previous nonextended name
01232                                         GUID  gg;
01233                                         CopyTo(prevguid,gg);
01234                                         CComBstrObj guidstr;
01235                                         CopyTo(gg, guidstr);
01236                                         connrecent = conn.Left(conn.GetLength()-4)+_T("-")+CString(PutInCString(guidstr))+_T(".mta");
01237 
01238                                         bool sysmove = false, usermove = false;
01239                                         conn1.Empty();
01240                                         if(QueryParadigm(name, PutOut(conn1), &prevguid, REGACCESS_SYSTEM) == S_OK &&
01241                                                 conn1 == CComBSTR(conn)) {  // if it was correctly registered in system
01242                                                 if(RegisterParadigm(name, PutInBstr(connrecent), prevversion, prevguid, REGACCESS_TEST) != S_OK) {
01243                                                         AfxMessageBox(_T("Cannot register this paradigm file\n")
01244                                                                                   _T("an existing '.mta' file with the same name\n")
01245                                                                                   _T("is registered in the system registry\n")
01246                                                                                   _T("which you are not permitted to change.\n")
01247                                                                                   _T("You need to change the name or location\n")
01248                                                                                   _T("of the new paradigm file"));
01249                                                         return E_INVALID_USAGE;
01250                                                 }
01251                                                 sysmove = true;;
01252                                         }
01253                                         conn1.Empty();
01254                                         if(QueryParadigm(name, PutOut(conn1), &prevguid, REGACCESS_USER) == S_OK &&
01255                                                 conn1 == CComBSTR(conn)) {  // if it was correctly registered in user
01256                                                 usermove = true;;
01257                                         }
01258 
01259                                         if(!MoveFileEx(FILEPART(conn), FILEPART(connrecent), MOVEFILE_REPLACE_EXISTING)) {
01260                                                 COMTHROW(E_FILEOPEN);
01261                                         }
01262  
01263                                         if(sysmove) {
01264                                                 COMTHROW( RegisterParadigm( name, PutInBstr(connrecent), prevversion, prevguid, REGACCESS_SYSTEM) );
01265                                         }
01266                                         if(usermove) {
01267                                                 COMTHROW( RegisterParadigm( name, PutInBstr(connrecent), prevversion, prevguid, REGACCESS_USER) );
01268                                         }
01269                                 }
01270                           } catch(hresult_exception(&e)) {
01271                                         AfxMessageBox(CString(_T("Failure saving previous version of paradigm\n")) + 
01272                                                                         e.what() + 
01273                                                                         (e.hr == E_BINFILE?_T(" [Binary paradigm file (.mta) incompatibility]\nPossible reason: GME version 6 changed the binary format of paradigms."):_T("")) +
01274                                                                         _T("\nOld version will be overwritten"));
01275                                         connrecent.Empty();
01276                           }
01277                         }
01278 
01279                         IMgaMetaParserPtr parser;
01280                         COMTHROW(parser.CreateInstance(L"MGA.MgaMetaParser"));
01281                         parser->__Parse(_bstr_t(file), _bstr_t(conn));
01282                 }
01283 
01284                 CComBstrObj name;
01285                 CComVariant guid;
01286                 CComBstrObj version;
01287                 COMTHROW(GetMtaInfo(PutInBstr(conn), PutOut(name), PutOut(version), PutOut(guid)));
01288                 if(!connrecent.IsEmpty()) {
01289                         CComBstrObj namer;
01290                         CComVariant guidr;
01291                         CComBstrObj versionr;
01292                         COMTHROW(GetMtaInfo(PutInBstr(connrecent), PutOut(namer), PutOut(versionr), PutOut(guidr)));
01293                         // We should change existing registration only here, if the new GUID != the old
01294                 }
01295 
01296                 COMTHROW(RegisterParadigm( name, PutInBstr(conn), PutInBstr(version), guid, mode) );
01297                 if(newname) MoveTo(name, newname);
01298         } COMCATCH(;)
01299 }
01300 
01301 STDMETHODIMP CMgaRegistrar::RegisterParadigm(BSTR name, BSTR connstr, BSTR version, VARIANT guid, regaccessmode_enum mode)
01302 {
01303         CString cver(version); 
01304 
01305         COMTRY
01306         {
01307                 GUID guid2;
01308                 if (guid.vt == (VT_UI1 | VT_ARRAY) && GetArrayLength(guid) == sizeof(GUID))
01309                 {
01310                         CopyTo(guid, guid2);
01311                 }
01312                 else if (guid.vt == VT_BSTR)
01313                 {
01314                         CopyTo(guid.bstrVal, guid2);
01315                 }
01316                 else
01317                         COMTHROW(E_INVALIDARG);
01318 
01319                 CComBstrObj guid3;
01320                 CopyTo(guid2, guid3);
01321 
01322                 if(mode & RM_USER) {
01323                         CRegKey mga;
01324                         ERRTHROW(mga.Create(HKEY_CURRENT_USER, rootreg) );
01325 
01326                         CRegKey pars;
01327                         ERRTHROW( pars.Create(mga, _T("Paradigms")) );
01328 
01329                         CRegKey par;
01330                         ERRTHROW( par.Create(pars, CString(name)) );
01331 
01332 
01333                         ERRTHROW( par.SetStringValue( _T("CurrentVersion"), PutInCString(guid3)));
01334                         if (!cver.IsEmpty()) {
01335                                 ERRTHROW( par.SetStringValue( cver, PutInCString(guid3)));
01336                         }
01337                         CRegKey parg;
01338                         ERRTHROW( parg.Create(par, PutInCString(guid3)) );
01339 
01340                         ERRTHROW( parg.SetStringValue( _T("ConnStr"), CString(connstr)));
01341                 }
01342                 if(mode & (RM_SYS | RM_TEST)) {
01343                         CRegKey mga;
01344                         WIN32THROW(mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
01345 
01346                         CRegKey pars;
01347                         WIN32THROW( pars.Create(mga, _T("Paradigms"), 0, 0, KEY_READ | KEY_WRITE | KEY_WOW64_32KEY) );
01348 
01349                         CRegKey par;
01350 
01351                         if (mode & RM_SYS) {
01352                                 WIN32THROW( par.Create(pars, CString(name)) );
01353                                 CString gg      = QueryValue(par, _T("GUID"));
01354                                 CString gc      = QueryValue(par, _T("ConnStr"));
01355                                 par.DeleteValue(_T("GUID"));
01356                                 par.DeleteValue(_T("ConnStr"));
01357                                 if(!gc.IsEmpty() && !gg.IsEmpty()) {
01358                                         CRegKey parg2;
01359                                         WIN32THROW( parg2.Create(par, gg) );
01360                                         WIN32THROW( parg2.SetStringValue( _T("ConnStr"), gc) );
01361                                 }
01362 
01363                                 WIN32THROW( par.SetStringValue( _T("CurrentVersion"), PutInCString(guid3)));
01364                                 if (!cver.IsEmpty()) {
01365                                         WIN32THROW( par.SetStringValue( cver, PutInCString(guid3)));
01366                                 }
01367                                 CRegKey parg;
01368                                 WIN32THROW( parg.Create(par, PutInCString(guid3)) );
01369 
01370                                 WIN32THROW( parg.SetStringValue( _T("ConnStr"), CString(connstr)));
01371                         } else {
01372                                 LONG res = par.Open(pars, CString(name));
01373                                 if(res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND) WIN32THROW(res);
01374                         }
01375                 }
01376                 if ((!(mode & RM_USER) || IsAssociated_hive(L"Mga.AddOn.ConstraintManager", name, HKEY_CURRENT_USER) != Tristate_Disabled) &&
01377                         (!(mode & RM_SYS) || IsAssociated_hive(L"Mga.AddOn.ConstraintManager", name, HKEY_LOCAL_MACHINE) != Tristate_Disabled)) {
01378                         Associate(CComBSTR(L"Mga.AddOn.ConstraintManager"), name, mode); // no error checking
01379                 }
01380         }
01381         COMCATCH(;)
01382 }
01383 
01384 STDMETHODIMP CMgaRegistrar::QueryParadigmAllGUIDs(BSTR parname, VARIANT *guidstrs, regaccessmode_enum mode) {
01385         CHECK_OUT(guidstrs);
01386         COLE2CT parname2(parname);
01387         CString pname(parname2); 
01388 
01389         COMTRY
01390         {
01391                 CStringArray ret;
01392                 if(mode & RM_USER) {
01393                         CRegKey par;
01394                         LONG res = par.Open(HKEY_CURRENT_USER, rootreg+_T("\\Paradigms\\") + pname, KEY_READ);
01395                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01396                         if(res == ERROR_SUCCESS) {
01397                                 for(int index = 0;; ++index) {
01398                                         TCHAR name[1024];
01399                                         LONG err = RegEnumKey(par, index, name, 1024);
01400                                         if( err == ERROR_NO_MORE_ITEMS )
01401                                                 break;
01402                                         ERRTHROW( err );
01403 
01404                                         REVOKE_SYS2(mode);
01405                                         ret.Add(name);
01406                                 }
01407 
01408                         }
01409                 }
01410                 int retlen = ret.GetSize();
01411 
01412                 if(mode & RM_SYSDOREAD) {
01413                         CRegKey par;
01414                         LONG res = par.Open(HKEY_LOCAL_MACHINE, rootreg+_T("\\Paradigms\\") + pname, KEY_READ | KEY_WOW64_32KEY);
01415                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01416                         if(res == ERROR_SUCCESS) {
01417                                 CString cur = QueryValue(par, _T("CurrentVersion"));
01418                                 if(!cur.IsEmpty()) {  // New style: Connection strings are stored under GUID subkeys
01419                                   for(int index = 0;; ++index) {
01420                                         TCHAR name[1024];
01421                                         LONG err = RegEnumKey(par, index, name, 1024);
01422                                         if( err == ERROR_NO_MORE_ITEMS )
01423                                                 break;
01424                                         ERRTHROW( err );
01425                                         int j;
01426                                         for(j = 0; j < retlen; j++) {           // Make sure, name is not present already, if yes system copy is ignored
01427                                                 if(!ret[j].CompareNoCase(name)) break;
01428                                         }
01429                                         if(j != retlen) continue;
01430                                         ret.Add(name);
01431                                   }
01432                                 }
01433                                 else {
01434                                         CString name = QueryValue(par, _T("GUID"));
01435                                         int j;
01436                                         for(j = 0; j < retlen; j++) {           // Make sure, name is not present already, if yes system copy is ignored
01437                                                 if(!ret[j].CompareNoCase(name)) break;
01438                                         }
01439                                         if(j == retlen) ret.Add(name);
01440                                 }
01441                         }
01442                 }
01443 
01444 
01445                 CopyTo(ret, guidstrs);
01446         }
01447         COMCATCH(;)
01448 }
01449 
01450 
01451 STDMETHODIMP CMgaRegistrar::QueryParadigm(BSTR parname, BSTR *connstr, VARIANT *guid, regaccessmode_enum mode)
01452 {
01453         CHECK_OUT(connstr);
01454 //      CHECK_OUT(guid);
01455 
01456         COMTRY
01457         {
01458                 CString pname = parname;
01459 
01460                 CRegKey subk;
01461                 CString guidact;
01462 
01463                 CComBstrObj inguidstr;
01464                 if(guid->vt != VT_EMPTY && guid->vt != VT_NULL) {
01465                         GUID g;
01466                         CopyTo(*guid, g);
01467                         CopyTo(g, inguidstr);
01468 //                      if(inguidstr == L"{00000000-0000-0000-0000-000000000000}") inguidstr = NULL;
01469                 }
01470 
01471                 LONG res;
01472 
01473                 if(mode & RM_USER) {
01474                         CRegKey par;
01475                         res = par.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms\\") + pname, KEY_READ);
01476                         if(res == ERROR_SUCCESS) {
01477                                 if(inguidstr == NULL) {
01478                                         guidact = QueryValue(par, _T("CurrentVersion"));
01479                                         if(guidact.IsEmpty()) res = ERROR_FILE_NOT_FOUND;
01480                                 }
01481                                 else
01482                                         guidact = inguidstr;
01483                         }
01484                         if(res == ERROR_SUCCESS) res = subk.Open(par, guidact, KEY_READ);
01485                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01486                         if(res == ERROR_SUCCESS)   mode = REGACCESS_USER;
01487                 }
01488 
01489                 if(mode & RM_SYSDOREAD) {
01490                         CRegKey par;
01491                         res = par.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms\\") + pname, KEY_READ | KEY_WOW64_32KEY);
01492                         if(res == ERROR_SUCCESS) {
01493                                 CString cur = QueryValue(par, _T("CurrentVersion"));
01494                                 if (cur.IsEmpty() && inguidstr == NULL) {
01495                                         guidact = QueryValue(par, _T("GUID"));
01496                                         if (inguidstr != NULL && inguidstr != CComBSTR(guidact))
01497                                                 COMTHROW(E_NOTFOUND);
01498                                         subk.Attach(par.Detach());
01499                                 }
01500                                 else {
01501                                         if (inguidstr == NULL)
01502                                                 guidact = cur;
01503                                         else
01504                                                 guidact = inguidstr;
01505                                         res = subk.Open(par, guidact, KEY_READ);
01506                                         if (res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND)
01507                                                 ERRTHROW(res);
01508                                 }
01509                         }
01510                 }
01511                 if (subk == NULL)
01512                 {
01513                         CString error;
01514                         if (inguidstr)
01515                                 error.Format(L"Paradigm '%s' with GUID '%s' is not registered.", pname, inguidstr);
01516                         else
01517                                 error.Format(L"Paradigm '%s' is not registered.", pname);
01518                         SetErrorInfo(error);
01519                         return E_NOTFOUND;
01520                 }
01521 
01522 
01523                 CopyTo(QueryValue(subk, _T("ConnStr")), connstr);
01524 
01525                 if(inguidstr == NULL) {
01526                         GUID g;
01527                         CopyTo(CComBSTR(guidact),g); 
01528                         CopyTo(g, guid);
01529                 }
01530         }
01531         COMCATCH(;)
01532 }
01533 
01534 STDMETHODIMP CMgaRegistrar::get_ParadigmGUIDString(regaccessmode_enum mode, BSTR parname, BSTR *guidstr)
01535 {
01536         CHECK_OUT(guidstr);
01537         COMTRY
01538         {
01539                 CComBSTR connstr;
01540                 CComVariant guid;
01541                 HRESULT hr = QueryParadigm(parname, &connstr, &guid, mode);
01542                 if (FAILED(hr))
01543                         return hr;
01544                 GUID g;
01545                 CopyTo(guid, g);
01546                 CopyTo(g, guidstr);
01547         }
01548         COMCATCH(;)
01549 }
01550 
01551 STDMETHODIMP CMgaRegistrar::VersionFromGUID(BSTR name, VARIANT guid, BSTR *ver, regaccessmode_enum mode)
01552 {
01553         CHECK_OUT(ver);
01554 
01555         bool found = false;
01556         COMTRY
01557         {
01558                 GUID gg;
01559                 CopyTo(guid,gg);
01560                 CComBstrObj guidbstr;
01561                 CopyTo(gg, guidbstr);
01562 
01563                 LONG res;
01564 
01565                 if(mode & RM_USER) {
01566                         CRegKey par;
01567                         res = par.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms\\")+name, KEY_READ);
01568                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01569                         if(res == ERROR_SUCCESS) {
01570                                 mode = REGACCESS_USER;
01571                                 for(int index = 0;; ++index) {
01572                                         TCHAR name[512];
01573                                         DWORD namesize = sizeof(name) / sizeof(name[0]);
01574                                         TCHAR value[512];
01575                                         DWORD valuesize = sizeof(value);
01576                                         DWORD valtype;
01577 
01578                                         LONG err = RegEnumValue(par, index, name, &namesize, NULL, &valtype, (LPBYTE)value, &valuesize);
01579                                         if( err == ERROR_NO_MORE_ITEMS )
01580                                                 break;
01581                                         ERRTHROW( err );
01582                                         if (valtype == REG_SZ) {
01583                                                 CString cver(value);
01584                                                 if (cver.Compare(PutInCString(guidbstr)) == 0) {
01585                                                         CString namestr(name);
01586                                                         if (namestr.CompareNoCase(_T("CurrentVersion")) != 0) {
01587                                                                 found = true;
01588                                                                 CopyTo(namestr, ver);
01589                                                         }
01590                                                 }
01591                                         }
01592                                 }
01593                         }
01594                 }
01595                 if(mode & (RM_SYSDOREAD)) {
01596                         CRegKey par;
01597                         res = par.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms\\")+name, KEY_READ | KEY_WOW64_32KEY);
01598                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01599                         if(res == ERROR_SUCCESS) {
01600                                 for(int index = 0;; ++index) {
01601                                         TCHAR name[512];
01602                                         DWORD namesize = sizeof(name) / sizeof(name[0]);
01603                                         TCHAR value[512];
01604                                         DWORD valuesize = sizeof(value);
01605                                         DWORD valtype;
01606 
01607                                         LONG err = RegEnumValue(par, index, name, &namesize, NULL, &valtype, (BYTE*)value, &valuesize);
01608                                         if( err == ERROR_NO_MORE_ITEMS )
01609                                                 break;
01610                                         ERRTHROW( err );
01611                                         if (valtype == REG_SZ) {
01612                                                 CString cver(value);
01613                                                 if (cver.Compare(PutInCString(guidbstr)) == 0) {
01614                                                         CString namestr(name);
01615                                                         if (namestr.CompareNoCase(_T("CurrentVersion")) != 0) {
01616                                                                 found = true;
01617                                                                 CopyTo(namestr, ver);
01618                                                         }
01619                                                 }
01620                                         }
01621                                 }
01622                         }
01623                 }
01624                 if (!found)
01625                 {
01626                         SetErrorInfo(E_NOTFOUND);
01627                         return(E_NOTFOUND);
01628                 }
01629         }
01630         COMCATCH(;)
01631 }
01632 
01633 STDMETHODIMP CMgaRegistrar::GUIDFromVersion(BSTR name, BSTR ver, VARIANT* guid, regaccessmode_enum mode)
01634 {
01635         CHECK_OUT(guid);
01636 
01637         CString verstr = ver;
01638         CString gstr;
01639 
01640         COMTRY
01641         {
01642                 LONG res;
01643 
01644                 if(mode & RM_USER) {
01645                         CRegKey par;
01646                         res = par.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms\\")+name, KEY_READ);
01647                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01648                         if(res == ERROR_SUCCESS) { 
01649                                 gstr = QueryValue(par, verstr);
01650                                 if (!gstr.IsEmpty()) {
01651                                         mode = REGACCESS_USER;
01652                                 }
01653                         }
01654                 }
01655                 if(mode & (RM_SYSDOREAD)) {
01656                         CRegKey par;
01657                         res = par.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms\\")+name, KEY_READ | KEY_WOW64_32KEY);
01658                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01659                         if(res == ERROR_SUCCESS) { 
01660                                 gstr = QueryValue(par, verstr);
01661                         }
01662                 }
01663 
01664                 if (gstr.IsEmpty()) {
01665                         CString error;
01666                         if (SysStringLen(ver))
01667                                 error.Format(L"Paradigm '%s' with version '%s' is not registered.", name, ver);
01668                         else
01669                                 error.Format(L"Paradigm '%s' is not registered.", name);
01670                         SetErrorInfo(error);
01671                         return E_NOTFOUND;
01672                 }
01673 
01674                 GUID g;
01675                 CopyTo(CComBSTR(gstr),g); 
01676                 CopyTo(g, guid);
01677         }
01678         COMCATCH(;)
01679 }
01680 
01681 
01682 STDMETHODIMP CMgaRegistrar::UnregisterParadigmGUID(BSTR name, VARIANT v, regaccessmode_enum mode)
01683 {                               // it cannot be unregistered if it is the current version
01684         COMTRY
01685         {
01686                 GUID gg;
01687                 CopyTo(v,gg);
01688                 CComBstrObj guidbstr;
01689                 CopyTo(gg, guidbstr);
01690 
01691                 if(mode & RM_USER) {
01692                         CRegKey par;
01693                         ERRTHROW( par.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms\\")+name) );
01694                         CString cur = QueryValue(par, _T("CurrentVersion"));
01695                         if(cur.Compare(PutInCString(guidbstr)) == 0) {
01696                                 COMTHROW(E_INVALID_USAGE);
01697                         }
01698                         
01699                         for(int index = 0;; ++index) {
01700                                 TCHAR name[512];
01701                                 DWORD namesize = sizeof(name) / sizeof(name[0]);
01702                                 TCHAR value[512];
01703                                 DWORD valuesize = sizeof(value);
01704                                 DWORD valtype;
01705 
01706                                 LONG err = RegEnumValue(par, index, name, &namesize, NULL, &valtype, (BYTE*)value, &valuesize);
01707                                 if( err == ERROR_NO_MORE_ITEMS )
01708                                         break;
01709                                 ERRTHROW( err );
01710                                 if (valtype == REG_SZ) {
01711                                         CString cver(value);
01712                                         if (cver.Compare(PutInCString(guidbstr)) == 0) {
01713                                                 RegDeleteValue(par, name);
01714                                         }
01715                                 }
01716                         }
01717 
01718                         ERRTHROW( par.RecurseDeleteKey(PutInCString(guidbstr)) );
01719                 }
01720                 if(mode & (RM_SYS | RM_TEST)) {
01721                         CRegKey par;
01722                         ERRTHROW( par.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms\\")+name, KEY_READ | KEY_WRITE | KEY_WOW64_32KEY) );
01723                         CString cur = QueryValue(par, _T("CurrentVersion"));
01724                         if(cur.Compare(PutInCString(guidbstr)) == 0) {
01725                                 COMTHROW(E_INVALID_USAGE);
01726                         }
01727                         if(mode & RM_SYS) {
01728                                 ERRTHROW( par.RecurseDeleteKey(PutInCString(guidbstr)) );
01729                                 for(int index = 0;; ++index) {
01730                                         TCHAR name[512];
01731                                         DWORD namesize = sizeof(name) / sizeof(name[0]);
01732                                         TCHAR value[512];
01733                                         DWORD valuesize = sizeof(value);
01734                                         DWORD valtype;
01735 
01736                                         LONG err = RegEnumValue(par, index, name, &namesize, NULL, &valtype, (BYTE*)value, &valuesize);
01737                                         if( err == ERROR_NO_MORE_ITEMS )
01738                                                 break;
01739                                         ERRTHROW( err );
01740                                         if (valtype == REG_SZ) {
01741                                                 CString cver(value);
01742                                                 if (cver.Compare(PutInCString(guidbstr)) == 0) {
01743                                                         RegDeleteValue(par, name);
01744                                                 }
01745                                         }
01746                                 }
01747                         }
01748                         if(mode & RM_TEST) ERRTHROW( par.Open(par, PutInCString(guidbstr)) );
01749                 }
01750         }
01751         COMCATCH(;)
01752 }
01753 
01754 STDMETHODIMP CMgaRegistrar::UnregisterParadigm(BSTR name, regaccessmode_enum mode)
01755 {
01756         COMTRY
01757         {
01758                 if(mode & RM_USER) {
01759                         CRegKey pars;
01760                         LONG res = pars.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms"));
01761                         if(!res) res = pars.RecurseDeleteKey(CString(name));
01762                         if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
01763                         ERRTHROW(res);
01764                 }
01765                 if(mode & (RM_SYS | RM_TEST)) {
01766                         CRegKey pars;
01767                         LONG res = pars.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms"), KEY_READ | KEY_WRITE | KEY_WOW64_32KEY);
01768                         if(!res) {
01769                                 if(mode & RM_SYS) res = pars.RecurseDeleteKey(PutInCString(name));
01770                                 if(mode & RM_TEST) res = pars.Open(pars, PutInCString(name));
01771                         }
01772                         if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
01773                         ERRTHROW(res);
01774                 }
01775         }
01776         COMCATCH(;)
01777 }
01778 
01779 // throws hresult_exception
01780 void GetComponents_(HKEY hive, CStringArray& ret) {
01781         CRegKey comps;
01782         LONG res = comps.Open(hive, rootreg + _T("\\Components"), KEY_READ);
01783         if (res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND)
01784                 COMTHROW(HRESULT_FROM_WIN32(res));
01785         if (res == ERROR_SUCCESS) {
01786                 for (int index = 0;; ++index) {
01787                         TCHAR name[1024];
01788                         LONG err = RegEnumKey(comps, index, name, 1024);
01789                         if (err == ERROR_NO_MORE_ITEMS)
01790                                 break;
01791                         ERRTHROW(err);
01792 
01793                         CRegKey comp;
01794                         err = comp.Open(comps, name, KEY_READ);
01795                         DWORD type2;
01796                         if (err == ERROR_SUCCESS)
01797                                 err = comp.QueryDWORDValue(_T("Type"), type2);
01798                         if (err != ERROR_SUCCESS)
01799                                 continue;
01800                         if((type2 & COMPONENTTYPE_SYSREGREF) != 0) { 
01801                                 continue;
01802                         }
01803                         // Make sure name is not present already
01804                         int j;
01805                         for (j = 0; j < ret.GetSize(); j++) {
01806                                 if (!ret[j].CompareNoCase(name))
01807                                         break;
01808                         }
01809                         if (j != ret.GetSize())
01810                                 continue;
01811                         ret.Add(name);
01812                 }
01813         }
01814 }
01815 
01816 STDMETHODIMP CMgaRegistrar::get_Components(regaccessmode_enum mode, VARIANT *progids)
01817 {
01818         CHECK_OUT(progids);
01819 
01820         COMTRY
01821         {
01822                 CStringArray ret;
01823                 if (mode & REGACCESS_USER)
01824                         GetComponents_(HKEY_CURRENT_USER, ret);
01825                 if (mode & REGACCESS_SYSTEM)
01826                         GetComponents_(HKEY_LOCAL_MACHINE, ret);
01827                 CopyTo(ret, progids);
01828         }
01829         COMCATCH(;)
01830 }
01831 
01832 template<typename Functor>
01833 void TokenizeParadigmString(const CString& paradigms, Functor& x) {
01834         CStringList ret;
01835         int curPos = 0;
01836         CString token = paradigms.Tokenize(_T(" ;,\n\t"), curPos);
01837         while (token != _T("")) {
01838                 x(token);
01839                 token = paradigms.Tokenize(_T(" ;,\n\t"), curPos);
01840         }
01841 }
01842 
01843 STDMETHODIMP CMgaRegistrar::RegisterComponent(BSTR progid, componenttype_enum type, BSTR desc, regaccessmode_enum mode)
01844 {
01845         COMTRY
01846         {
01847                 CComBstrObj paradigms(OLESTR("*"));
01848                 if(!(type & COMPONENTTYPE_PARADIGM_INDEPENDENT)) {
01849                         paradigms.Empty();
01850                         CComPtr<IMgaComponent> comp;
01851                         HRESULT hr = CreateMgaComponent(comp, progid);
01852                         if(!comp)
01853                         {
01854                                 _bstr_t error;
01855                                 GetErrorInfo(hr, error.GetAddress());
01856                                 if (!static_cast<LPOLESTR>(error))
01857                                         error = L"Unknown error";
01858                                 throw_com_error(E_MGA_COMPONENT_ERROR, _bstr_t(L"Could not create: ") + progid + L": " + error);
01859                         }
01860                         COMTHROW(comp->get_Paradigm(PutOut(paradigms)));
01861                 }
01862                 if(mode & RM_USER) {
01863                         CRegKey mga;
01864                         ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) );
01865                         CRegKey comps;
01866                         ERRTHROW( comps.Create(mga, _T("Components")) );
01867                         CRegKey comp;
01868                         ERRTHROW( comp.Create(comps, PutInCString(progid)) );
01869 
01870                         ERRTHROW( comp.SetDWORDValue( _T("Type"), (DWORD)type));
01871 
01872                         ERRTHROW( comp.SetStringValue( _T("Description"), PutInCString(desc)));
01873                         if(paradigms.Length()) {
01874                                 TokenizeParadigmString(PutInCString(paradigms), [&comp](const CString& par) {
01875                                         ERRTHROW(comp.SetStringValue(_T("Paradigm"), par));
01876                                 });
01877                         }
01878                 }
01879                 if(mode & (RM_SYS | RM_TEST)) {
01880                         CRegKey mga;
01881                         ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) );
01882                         CRegKey comps;
01883                         ERRTHROW( comps.Create(mga, _T("Components")) );
01884                         if(mode & RM_SYS) {
01885                                 CRegKey comp;
01886                                 ERRTHROW( comp.Create(comps, PutInCString(progid)) );
01887         
01888                                 ERRTHROW( comp.SetDWORDValue( _T("Type"), (DWORD)type));
01889 
01890                                 ERRTHROW( comp.SetStringValue( _T("Description"), PutInCString(desc)));
01891                                 TokenizeParadigmString(PutInCString(paradigms), [&comp](const CString& par) {
01892                                         ERRTHROW(comp.SetStringValue(_T("Paradigm"), par));
01893                                 });
01894                         }
01895                         else {
01896                                 CRegKey comp;
01897                                 LONG res = comp.Open(comps, PutInCString(progid));
01898                                 if(res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01899                         }
01900                 }
01901         }
01902         COMCATCH(;)
01903 }
01904 
01905 // FIXME: mode is ignored. It should be removed next interface-breaking change
01906 STDMETHODIMP CMgaRegistrar::QueryComponent(BSTR progid, componenttype_enum *type, BSTR *desc, regaccessmode_enum mode)
01907 {
01908         CHECK_OUT(type);
01909         if(desc) CHECK_OUT(desc);
01910         CString progidstr = PutInCString(progid);
01911 
01912         COMTRY
01913         {
01914                 DWORD dwType = -1;
01915                 CString strDesc;
01916                 HKEY hives[] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
01917                 for (int i = 0; i < 2; i++) {
01918                         CRegKey comp;
01919                         LONG res = comp.Open(hives[i], rootreg+_T("\\Components\\")+progidstr, KEY_READ);
01920                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01921                         if(res == ERROR_SUCCESS) {
01922                                 comp.QueryDWORDValue(_T("Type"), dwType);
01923                                 ULONG count = 0;
01924                                 res = comp.QueryStringValue(_T("Description"), NULL, &count);
01925                                 if (strDesc == _T("") && res == ERROR_SUCCESS) {
01926                                         CString ret;
01927                                         if (comp.QueryStringValue(_T("Description"), ret.GetBufferSetLength(count), &count) == ERROR_SUCCESS)
01928                                                 strDesc = ret;
01929                                 }
01930                         }
01931                 }
01932                 if (dwType == -1 || !(dwType & COMPONENTTYPE_ALL))
01933                         COMTHROW(E_NOTFOUND);
01934                 
01935                 if (type)
01936                         *type = (componenttype_enum)dwType;
01937                 if (desc && strDesc != _T(""))
01938                         CopyTo(strDesc, desc);
01939                 return S_OK;
01940         }
01941         COMCATCH(;)
01942 }
01943 
01944 STDMETHODIMP CMgaRegistrar::UnregisterComponent(BSTR progid, regaccessmode_enum mode)
01945 {
01946         COMTRY
01947         {
01948 //              if(mode & RM_USER) {
01949                 if(mode & (RM_USER | RM_SYS) ){
01950                         CRegKey comps;
01951                         LONG res = comps.Open(HKEY_CURRENT_USER, rootreg + _T("\\Components"));
01952 
01953                         DWORD type2 = 0;
01954                         if(!res) {
01955                                 CRegKey comp;
01956                                 res =  comp.Open(comps, PutInCString(progid), KEY_READ);
01957                                 if(!res) comp.QueryDWORDValue( _T("Type"), type2);
01958                         }
01959 
01960                         if((mode & RM_USER) || (type2 & COMPONENTTYPE_SYSREGREF) != 0 ) {
01961                                 if (!res) res = comps.RecurseDeleteKey(PutInCString(progid));
01962                                 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
01963                                 ERRTHROW(res);
01964                         }
01965                 }
01966                 if(mode & (RM_SYS | RM_TEST)) {
01967                         CRegKey comps;
01968                         LONG res = comps.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components"));
01969                         if(!res) {
01970                                 if(mode & RM_SYS) res = comps.RecurseDeleteKey(PutInCString(progid));
01971                                 if(mode & RM_TEST) res = comps.Open(comps, PutInCString(progid));
01972                         }
01973                         if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
01974                         ERRTHROW(res);
01975                 }
01976         }
01977         COMCATCH(;)
01978 }
01979 
01980 
01981 STDMETHODIMP CMgaRegistrar::put_ComponentExtraInfo(regaccessmode_enum mode, 
01982                                                                                                    BSTR progid, BSTR name, BSTR newVal) {
01983         CString progidstr = PutInCString(progid);
01984 
01985         COMTRY
01986         {
01987                 if(mode & RM_USER) {
01988                         CRegKey comp;
01989                         LONG res = comp.Open(HKEY_CURRENT_USER, rootreg+_T("\\Components\\")+progidstr);
01990                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
01991                         if(res == ERROR_SUCCESS) {
01992                                 DWORD type2;
01993                                 ERRTHROW( comp.QueryDWORDValue( _T("Type"), type2));
01994 
01995                                 if((type2 & COMPONENTTYPE_ALL)) { 
01996                                         if(!newVal) { ERRTHROW( comp.DeleteValue(PutInCString(name)) );  }
01997                                         else            { ERRTHROW( comp.SetStringValue( PutInCString(name), PutInCString(newVal))); }
01998                                 }
01999                         }
02000                 }
02001                 if(mode & (RM_SYS | RM_TEST)) {
02002                         CRegKey comp;
02003                         LONG res = comp.Open(HKEY_LOCAL_MACHINE, rootreg+_T("\\Components\\")+progidstr);
02004                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
02005                         if(res == ERROR_SUCCESS) {
02006                                 DWORD type2;
02007                                 ERRTHROW( comp.QueryDWORDValue( _T("Type"), type2));
02008 
02009                                 if((mode & RM_SYS) && (type2 & COMPONENTTYPE_ALL)) { 
02010                                         if(!newVal) { ERRTHROW( comp.DeleteValue(PutInCString(name)) );  }
02011                                         else            { ERRTHROW( comp.SetStringValue( PutInCString(name), PutInCString(newVal))); }
02012                                 }
02013                         }
02014                 }
02015         
02016         } COMCATCH(;)
02017 }
02018 
02019 // FIXME: mode is ignored. It should be removed next interface-breaking change
02020 STDMETHODIMP CMgaRegistrar::get_ComponentExtraInfo(regaccessmode_enum mode, 
02021                                                                                                    BSTR progid, BSTR name, BSTR* pVal) {
02022         CHECK_OUT(pVal);
02023         CString progidstr = PutInCString(progid);
02024 
02025         COMTRY
02026         {
02027                 HKEY hives[] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
02028                 for (int i = 0; i < 2; i++) {
02029                         CRegKey comp;
02030                         LONG res = comp.Open(hives[i], rootreg+_T("\\Components\\")+progidstr, KEY_READ);
02031                         if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
02032                         if(res == ERROR_SUCCESS) {
02033                                 ULONG count = 0;
02034                                 res = comp.QueryStringValue(PutInCString(name), NULL, &count);
02035                                 if (res == ERROR_SUCCESS) {
02036                                         CString ret;
02037                                         if (comp.QueryStringValue(PutInCString(name), ret.GetBufferSetLength(count), &count) == ERROR_SUCCESS) {
02038                                                 CopyTo(ret, pVal);
02039                                                 return S_OK;
02040                                         }
02041                                 }
02042                         }
02043                 }
02044                 return E_NOTFOUND;
02045         }
02046         COMCATCH(;)
02047 }
02048 
02049 
02050 STDMETHODIMP CMgaRegistrar::get_LocalDllPath(BSTR progid, BSTR* pVal) {
02051         CHECK_OUT(pVal);
02052         COMTRY
02053         {
02054                 CString m_strProgId = PutInCString(progid);
02055                 CRegKey comp;
02056                 CString m_strClassId;
02057                 for(int i = 0; i < 10; i++) {
02058                         LONG res = comp.Open(HKEY_CLASSES_ROOT, m_strProgId + _T("\\CLSID"), KEY_READ);
02059                         if(res == ERROR_SUCCESS) {
02060                                 m_strClassId = QueryValue(comp,_T("") );
02061                                 break;
02062                         }
02063                         else {
02064                                 res = comp.Open(HKEY_CLASSES_ROOT, m_strProgId + _T("\\CurVer"), KEY_READ);
02065                                 if(res != ERROR_SUCCESS) COMTHROW(E_NOTFOUND);
02066                                 m_strProgId = QueryValue(comp, _T("") );
02067                                 comp.Close();
02068                         }
02069                 }
02070                 if(m_strClassId.IsEmpty()) COMTHROW(E_NOTFOUND);
02071 
02072                 LONG res = comp.Open(HKEY_CLASSES_ROOT, _T("CLSID\\") + m_strClassId + _T("\\InprocServer32"), KEY_READ);
02073                 CString m_strPath;
02074                 if(res == ERROR_SUCCESS) {
02075                         m_strPath = QueryValue(comp, _T("") );
02076                         if (m_strPath == _T("mscoree.dll")) {
02077                                 CString data;
02078                                 ULONG count = 1024;
02079                                 if (comp.QueryStringValue(_T("CodeBase"), data.GetBufferSetLength(count), &count) == ERROR_SUCCESS) {
02080                                         m_strPath = data;
02081                                         m_strPath = m_strPath.Right(m_strPath.GetLength() - 8);
02082                                         m_strPath.Replace('/', '\\');
02083                                 } else {
02084                                         count = 1024;
02085                                         if (comp.QueryStringValue(_T("Assembly"), data.GetBufferSetLength(count), &count) == ERROR_SUCCESS) {
02086                                                 m_strPath = _T("GAC: ");
02087                                                 m_strPath += data;
02088                                         }
02089                                 }
02090                         } else {
02091                                 // VS2012 puts quotes around the dll path
02092                                 if (m_strPath[0] == L'\"') {
02093                                         m_strPath = m_strPath.Right(m_strPath.GetLength() - 1);
02094                                 }
02095                                 if (m_strPath[m_strPath.GetLength() - 1] == L'\"') {
02096                                         m_strPath = m_strPath.Left(m_strPath.GetLength() - 1);
02097                                 }
02098                         }
02099                 }
02100                 CopyTo(m_strPath, pVal);
02101 
02102         }
02103         COMCATCH(;)
02104 }
02105 
02106 STDMETHODIMP CMgaRegistrar::get_AssociatedComponents(BSTR paradigm, 
02107         componenttype_enum type, regaccessmode_enum mode, VARIANT *progids)
02108 {
02109         CHECK_OUT(progids);
02110         type = (componenttype_enum)(type & COMPONENTTYPE_ALL);
02111 
02112         COMTRY
02113         {
02114                 CStringArray ret;
02115 
02116                 CString paradigmstr = paradigm;
02117 
02118                 CStringArray components;
02119                 if (mode & REGACCESS_USER)
02120                         GetComponents_(HKEY_CURRENT_USER, components);
02121                 if (mode & REGACCESS_SYSTEM)
02122                         GetComponents_(HKEY_LOCAL_MACHINE, components);
02123                 for (int i = 0; i < components.GetSize(); i++) {
02124                         componenttype_enum comptype = COMPONENTTYPE_NONE;
02125                         PutInBstr progid(components.GetAt(i));
02126                         CComBSTR desc;
02127                         COMTHROW(QueryComponent(progid, &comptype, &desc, REGACCESS_BOTH));
02128                         if ((comptype & type) && IsAssociated_regaccess(components.GetAt(i), paradigmstr, mode)) {
02129                                 ret.Add(components.GetAt(i));
02130                         }
02131                 }
02132                 CopyTo(ret, progids);
02133         }
02134         COMCATCH(;)
02135 }
02136 
02137 STDMETHODIMP CMgaRegistrar::get_AssociatedParadigms(BSTR progid, regaccessmode_enum mode, VARIANT *paradigms)
02138 {
02139         CHECK_OUT(paradigms);
02140 
02141         COMTRY
02142         {
02143 
02144                 CStringArray ret;
02145                 CString progidstr = PutInCString(progid);
02146 
02147                 VARIANT all_paradigms_;
02148                 VariantInit(&all_paradigms_);
02149                 COMTHROW(get_Paradigms(REGACCESS_BOTH, &all_paradigms_));
02150                 ATL::CComSafeArray<BSTR> all_paradigms;
02151                 all_paradigms.Attach(all_paradigms_.parray);
02152                 ASSERT(all_paradigms.GetDimensions() == 1);
02153                 for (LONG i = all_paradigms.GetLowerBound(); i <= all_paradigms.GetUpperBound(); i++) {
02154                         BSTR paradigm = all_paradigms.GetAt(i);
02155                         if (IsAssociated_regaccess(progidstr, PutInCString(paradigm), mode)) {
02156                                 ret.Add(static_cast<const CString&>(PutInCString(paradigm)));
02157                         }
02158                 }
02159 
02160                 CopyTo(ret, paradigms);
02161         }
02162         COMCATCH(;)
02163 }
02164 
02165 STDMETHODIMP CMgaRegistrar::Associate(BSTR progid, BSTR paradigm, regaccessmode_enum mode)
02166 {
02167         COLE2CT progid2(progid);
02168         CString pname(progid2);
02169         COMTRY
02170         {
02171                 bool somethingdone = false;
02172                 if(mode & RM_USER) {            
02173                         CRegKey comp;
02174                         LONG res = comp.Open(HKEY_CURRENT_USER, rootreg + _T("\\Components\\") + pname);
02175                         CRegKey assocs;
02176                         if(res == ERROR_FILE_NOT_FOUND) {   // try to create a shadow registry
02177                                 CRegKey comp1, mga;
02178                                 res = comp1.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components\\") + pname, KEY_READ);
02179                                 if(!res) res = mga.Create(HKEY_CURRENT_USER, rootreg);
02180                                 CRegKey comps;
02181                                 if(!res) res = ( comps.Create(mga, _T("Components")) );
02182                                 if(!res) res = ( comp.Create(comps, pname) );
02183                         }
02184                         if(res == ERROR_SUCCESS) res = assocs.Create(comp, _T("Associated"));
02185                         if(!res) assocs.SetStringValue( PutInCString(paradigm), _T(""));
02186                         if(!res) somethingdone = true;
02187                         if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
02188                         ERRTHROW(res);
02189                 }
02190                 if(mode & (RM_SYS | RM_TEST)) {
02191                         CRegKey comp;
02192                         LONG res = comp.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components\\") + pname);
02193                         if(mode & RM_SYS) {
02194                                 CRegKey assocs;
02195                                 if(!res) res = assocs.Create(comp, _T("Associated"));
02196                                 if(!res) res = assocs.SetStringValue( PutInCString(paradigm), _T(""));
02197                         }
02198                         else {
02199                                 CRegKey assocs;
02200                                 LONG res = assocs.Open(comp, _T("Associated"));
02201                                 if(res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res);
02202                         }
02203                         if(!res) somethingdone = true;
02204                 }
02205                 if(!somethingdone) COMTHROW(E_NOTFOUND);
02206         }
02207         COMCATCH(;)
02208 }
02209 
02210 STDMETHODIMP CMgaRegistrar::Disassociate(BSTR progid, BSTR paradigm, regaccessmode_enum mode)
02211 {
02212         COLE2CT progid2(progid);
02213         CString pname(progid2);
02214         COMTRY
02215         {
02216                 if(mode & RM_USER) {            
02217                         CRegKey comp;
02218                         LONG res = comp.Open(HKEY_CURRENT_USER, rootreg + _T("\\Components\\") + pname);
02219                         if (res == ERROR_FILE_NOT_FOUND) {
02220                                 CRegKey comp1, mga;
02221                                 res = comp1.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components\\") + pname, KEY_READ);
02222                                 if(!res) res = mga.Create(HKEY_CURRENT_USER, rootreg);
02223                                 CRegKey comps;
02224                                 if(!res) res = ( comps.Create(mga, _T("Components")) );
02225                                 if(!res) res = ( comp.Create(comps, pname) );
02226                         }
02227                         CRegKey assocs;
02228                         if(!res) res = assocs.Open(comp, _T("Associated"));
02229                         if (res == ERROR_FILE_NOT_FOUND) 
02230                                 res = assocs.Create(comp, _T("Associated"));
02231                         if (!res)
02232                                 res = assocs.SetStringValue(PutInCString(paradigm), _T("Disabled"));
02233                         if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
02234                         ERRTHROW(res);
02235                 }
02236                 if(mode & (RM_SYS | RM_TEST)) {
02237                         CRegKey comp;
02238                         LONG res = comp.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components\\") + pname);
02239                         CRegKey assocs;
02240                         if(!res) res = assocs.Open(comp, _T("Associated"));
02241                         if(mode & RM_SYS) {
02242                                 if(!res) res = assocs.DeleteValue(PutInCString(paradigm));
02243                         }
02244                         if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
02245                         ERRTHROW(res);
02246                 }
02247         }
02248         COMCATCH(;)
02249 }
02250 
02251 STDMETHODIMP CMgaRegistrar::IsAssociated(BSTR progid, BSTR paradigm, 
02252                                                                                 VARIANT_BOOL *is_ass, VARIANT_BOOL *can_ass, regaccessmode_enum mode){
02253         CHECK_IN(progid);
02254         CHECK_OUT(paradigm);
02255         CString progidstr = PutInCString(progid);
02256         CString parc = PutInCString(paradigm);
02257 
02258         COMTRY
02259         {
02260                 componenttype_enum type;
02261 
02262                 COMTHROW(QueryComponent(progid, &type, NULL, REGACCESS_PRIORITY));
02263 
02264                 if (is_ass) *is_ass = IsAssociated_regaccess(progidstr, parc, mode) ? VARIANT_TRUE : VARIANT_FALSE;
02265 
02266                 if (can_ass) *can_ass = VARIANT_FALSE;
02267                 VARIANT_BOOL can = VARIANT_FALSE;
02268                 CComBSTR pars;
02269                 get_ComponentExtraInfo(mode,progid,CComBSTR(L"Paradigm"), &pars);
02270                 if(!pars && !(type & COMPONENTTYPE_SCRIPT)) {
02271                         CComPtr<IMgaComponent> comp;
02272                         CreateMgaComponent(comp, progid);
02273                         if(!comp) COMTHROW(E_NOTFOUND);
02274                         COMTHROW(comp->get_Paradigm(&pars));
02275                         put_ComponentExtraInfo(REGACCESS_BOTH, progid, CComBSTR(L"Paradigm"), pars);  // just try
02276                 }
02277                 if(!pars) {
02278                         can = type & COMPONENTTYPE_PARADIGM_INDEPENDENT ? VARIANT_TRUE : VARIANT_FALSE;
02279                 }
02280                 else if(!wcscmp(pars, L"*")) {
02281                         can = VARIANT_TRUE;
02282                 }
02283                 else {
02284                         can = VARIANT_FALSE;
02285                         TokenizeParadigmString(PutInCString(pars), [&paradigm, &can](const CString& paradigm2) {
02286                                 if (static_cast<const CString &>(PutInCString(paradigm)) == paradigm2)
02287                                         can = VARIANT_TRUE;
02288                         });
02289                 }       
02290                 if(can_ass) *can_ass = can;
02291                 
02292         }
02293         COMCATCH(;)
02294 }
02295 
02296 
02297 // --- Actions
02298 typedef HRESULT (STDAPICALLTYPE *CTLREGPROC)();
02299 
02300 STDMETHODIMP CMgaRegistrar::RegisterComponentLibrary(BSTR path, regaccessmode_enum mode)
02301 {
02302         COMTRY
02303         {
02304                 HMODULE hModule = LoadLibrary(CString(path));
02305                 if( hModule == 0 ) {
02306                         HR_THROW(HRESULT_FROM_WIN32(GetLastError()));
02307                 }
02308 
02309                 CTLREGPROC DLLRegisterServer =
02310                         (CTLREGPROC)::GetProcAddress(hModule, "DllRegisterServer");
02311                 
02312                 if( DLLRegisterServer == NULL )
02313                 {
02314                         FreeLibrary(hModule);
02315                     using namespace MgaDotNetServices;
02316                         _RegistrarPtr reg;
02317                         COMTHROW(reg.CreateInstance(L"MGA.DotNetRegistrar"));
02318                         //COMTHROW(reg.CreateInstance(L"{0BB0C371-6835-4F09-A156-0BD8E3DF8216}", NULL, CLSCTX_INPROC));
02319                         reg->Register(_bstr_t(path));
02320 
02321                         return S_OK;
02322                 }
02323                 else
02324                 {
02325                         //c++ dll:
02326                         COMTHROW( DLLRegisterServer() );
02327                         FreeLibrary(hModule);
02328                 }
02329 
02330 
02331                 CComObjPtr<ITypeLib> typelib;
02332                 COMTHROW( LoadTypeLibEx(path, REGKIND_REGISTER, PutOut(typelib)) );
02333 
02334                 UINT index = typelib->GetTypeInfoCount();
02335                 while( index-- > 0 )
02336                 {
02337                         CComObjPtr<ITypeInfo> typeinfo;
02338                         COMTHROW( typelib->GetTypeInfo(index, PutOut(typeinfo)) );
02339 
02340                         TYPEATTR *typeattr = NULL;
02341                         COMTHROW( typeinfo->GetTypeAttr(&typeattr) );
02342                         ASSERT( typeattr != NULL );
02343 
02344                         try
02345                         {
02346                                 if( typeattr->typekind == TKIND_COCLASS )
02347                                 {
02348                                         CComPtr<IMgaComponent> component;
02349                                         // if( SUCCEEDED(typeinfo->CreateInstance(NULL, 
02350                                         //      __uuidof(IMgaComponent), (void**)PutOut(component))) )
02351                                         if (SUCCEEDED(CreateMgaComponent(component, typeattr->guid)))
02352                                         {
02353                                                 CComBstrObj desc;
02354                                                 COMTHROW( component->get_ComponentName(PutOut(desc)) );
02355 
02356                                                 componenttype_enum type;
02357                                                 COMTHROW( component->get_ComponentType(&type) );
02358 
02359                                                 LPOLESTR olestr;
02360                                                 COMTHROW( ProgIDFromCLSID(typeattr->guid, &olestr) );
02361                                                 CComBstrObj progid(olestr);
02362                                                 {
02363                                                         LPOLESTR pp = olestr + wcslen(olestr) - 2;
02364                                                         if(wcslen(olestr) > 2 && 
02365                                                                 pp[0] == '.' &&
02366                                                                 isdigit(pp[1]) ) {
02367                                                                 pp[0] = 0;
02368                                                                 CLSID tempGUID;
02369                                                                 HRESULT hr = CLSIDFromProgID(olestr, &tempGUID);
02370                                                                 if(hr == S_OK && tempGUID == typeattr->guid) {
02371                                                                         progid = CComBstrObj(olestr);
02372                                                                 }
02373                                                         }
02374                                                 }
02375 
02376                                                 COMTHROW( RegisterComponent(progid, type, desc, mode) );
02377                                                 CoTaskMemFree(olestr);
02378 
02379                                                 CString paradigms;
02380                                                 COMTHROW( component->get_Paradigm(PutOut(paradigms)) );
02381 
02382                                                 TokenizeParadigmString(paradigms, [this,&mode,&progid](const CString& par){
02383                                                         COMTHROW(Associate(progid, PutInBstr(par), mode));
02384                                                 });
02385                                         }
02386                                 }
02387 
02388                                 typeinfo->ReleaseTypeAttr(typeattr);
02389                         }
02390                         catch(hresult_exception &)
02391                         {
02392                                 typeinfo->ReleaseTypeAttr(typeattr);
02393                                 throw;
02394                         }
02395                 }
02396         }
02397         COMCATCH(;)
02398 }
02399 
02400 STDMETHODIMP CMgaRegistrar::UnregisterComponentLibrary(BSTR path, regaccessmode_enum mode)
02401 {
02402         COMTRY
02403         {
02404                 CComObjPtr<ITypeLib> typelib;
02405                 COMTHROW( LoadTypeLibEx(path, REGKIND_NONE, PutOut(typelib)) );
02406 
02407                 UINT index = typelib->GetTypeInfoCount();
02408                 while( index) //WAS: while( --index >= 0 ) // was an infinite loop with UINT
02409                 {
02410                         --index;
02411                         CComObjPtr<ITypeInfo> typeinfo;
02412                         COMTHROW( typelib->GetTypeInfo(index, PutOut(typeinfo)) );// index parameter with the range of 0 to GetTypeInfoCount() –1.
02413 
02414                         TYPEATTR *typeattr = NULL;
02415                         COMTHROW( typeinfo->GetTypeAttr(&typeattr) );
02416                         ASSERT( typeattr != NULL );
02417 
02418                         try
02419                         {
02420                                 if( typeattr->typekind == TKIND_COCLASS )
02421                                 {
02422                                         LPOLESTR olestr;
02423                                         if( SUCCEEDED(ProgIDFromCLSID(typeattr->guid, &olestr)) )
02424                                         {
02425                                                 CComBstrObj progid(olestr);
02426                                                 COMTHROW( UnregisterComponent(progid, mode) );
02427                                         }
02428                                 }
02429 
02430                                 typeinfo->ReleaseTypeAttr(typeattr);
02431                         }
02432                         catch(hresult_exception &)
02433                         {
02434                                 typeinfo->ReleaseTypeAttr(typeattr);
02435                                 throw;
02436                         }
02437                 }
02438 
02439                 // TODO: unregister the type library
02440         }
02441         COMCATCH(;)
02442 }