现在的位置: 首页 > 综合 > 正文

利用atl中注册com组件的方法来访问注册表

2013年12月02日 ⁄ 综合 ⁄ 共 20093字 ⁄ 字号 评论关闭

工作中需要一个快速编辑修改注册表的功能。记得atl中有那么一个通过脚本来访问编辑注册表的东东。于是,抠出其代码如下。其中删除了部分代码。删除的部分,原先atl是用来进行预处理替换操作的。

代码如下:

  1. class CRegParser
  2. {
  3. public:
  4.     CRegParser();
  5.     HRESULT  PreProcessBuffer(_In_z_ LPTSTR lpszReg, _Deref_out_opt_z_ LPTSTR* ppszReg);
  6.     HRESULT  RegisterBuffer(_In_z_ LPTSTR szReg, _In_ BOOL bRegister);
  7. protected:
  8.     static const int MAX_VALUE = 4096;
  9.     void    SkipWhiteSpace();
  10.     HRESULT NextToken(LPTSTR szToken);
  11.     HRESULT AddValue(CRegKey& rkParent, LPCTSTR szValueName, LPTSTR szToken);
  12.     BOOL    CanForceRemoveKey(LPCTSTR szKey);
  13.     BOOL    HasSubKeys(HKEY hkey);
  14.     BOOL    HasValues(HKEY hkey);
  15.     HRESULT RegisterSubkeys(LPTSTR szToken, HKEY hkParent, BOOL bRegister, BOOL bInRecovery = FALSE);
  16.     BOOL    IsSpace(TCHAR ch);
  17.     LPTSTR  m_pchCur;
  18.     HRESULT GenerateError(UINT) {return DISP_E_EXCEPTION;}
  19.     //HRESULT HandleReplacements(LPTSTR& szToken);
  20.     HRESULT SkipAssignment(LPTSTR szToken);
  21.     BOOL    EndOfVar() { return chQuote == *m_pchCur && chQuote != *CharNext(m_pchCur); }
  22.     static LPTSTR StrChr(LPTSTR lpsz, TCHAR ch);
  23.     static HKEY HKeyFromString(LPTSTR szToken);
  24.     static BYTE ChToByte(const TCHAR ch);
  25.     static BOOL VTFromRegType(LPCTSTR szValueType, VARTYPE& vt);
  26.     static const TCHAR* const rgszNeverDelete[];
  27.     static const int cbNeverDelete;
  28.     static const int MAX_TYPE = 4096;
  29.     // Implementation Helper
  30.     class CParseBuffer
  31.     {
  32.     public:
  33.         int nPos;
  34.         int nSize;
  35.         LPTSTR p;
  36.         CParseBuffer(int nInitial)
  37.         {
  38.             if (nInitial < 100)
  39.                 nInitial = 1000;
  40.             nPos = 0;
  41.             nSize = nInitial;
  42.             p = (LPTSTR) ::ATL::AtlCoTaskMemCAlloc(nSize,static_cast<ULONG>(sizeof(TCHAR)));
  43.             if (p != NULL)
  44.                 *p = NULL;
  45.         }
  46.         ~CParseBuffer()
  47.         {
  48.             CoTaskMemFree(p);
  49.         }
  50.         BOOL Append(const TCHAR* pch, int nChars)
  51.         {
  52.             ATLASSERT(p != NULL);
  53.             int newSize = nPos + nChars + 1;
  54.             if ((newSize <= nPos) || (newSize <= nChars))
  55.                 return FALSE;
  56.             if (newSize >= nSize)
  57.             {
  58.                 while (newSize >= nSize) {
  59.                     if (nSize > INT_MAX / 2)
  60.                     return FALSE;
  61.                     nSize *= 2;
  62.                 }
  63.                 LPTSTR pTemp = (LPTSTR)::ATL::AtlCoTaskMemRecalloc(p, nSize, sizeof(TCHAR));
  64.                 if (pTemp == NULL)
  65.                     return FALSE;
  66.                 p = pTemp;
  67.             }
  68.             if ((nPos < 0) || (nPos >= nSize) || nSize - nPos > nSize)
  69.                 return FALSE;
  70. #pragma warning(push)
  71. #pragma warning(disable: 22008)
  72.             /* Prefast false warning is fired here despite the all above checks */
  73.             Checked::memcpy_s(p + nPos, (nSize-nPos) * sizeof(TCHAR), pch, int(nChars * sizeof(TCHAR)));
  74.             nPos += nChars;
  75.             *(p + nPos) = NULL;
  76. #pragma warning(pop)
  77.             return TRUE;            
  78.         }
  79.         BOOL AddChar(const TCHAR* pch)
  80.         {
  81. #ifndef _UNICODE        
  82.             int nChars = int(CharNext(pch) - pch);
  83. #else
  84.             int nChars = 1;
  85. #endif
  86.             return Append(pch, nChars);
  87.         }
  88.         BOOL AddString(LPCOLESTR lpsz)
  89.         {
  90.             if (lpsz == NULL)
  91.             {
  92.                 return FALSE;
  93.             }
  94.             USES_CONVERSION_EX;
  95.             LPCTSTR lpszT = OLE2CT_EX(lpsz, _ATL_SAFE_ALLOCA_DEF_THRESHOLD);
  96.             if (lpszT == NULL)
  97.             {
  98.                 return FALSE;
  99.             }
  100.             return Append(lpszT, (int)lstrlen(lpszT));
  101.         }
  102.         LPTSTR Detach()
  103.         {
  104.             LPTSTR lp = p;
  105.             p = NULL;
  106.             nSize = nPos = 0;
  107.             return lp;
  108.         }
  109.     };
  110. };
  111. __declspec(selectany) const TCHAR* const CRegParser::rgszNeverDelete[] =
  112. {
  113.     _T("AppID"),
  114.     _T("CLSID"),
  115.     _T("Component Categories"),
  116.     _T("FileType"),
  117.     _T("Interface"),
  118.     _T("Hardware"),
  119.     _T("Mime"),
  120.     _T("SAM"),
  121.     _T("SECURITY"),
  122.     _T("SYSTEM"),
  123.     _T("Software"),
  124.     _T("TypeLib")
  125. };
  126. __declspec(selectany) const int CRegParser::cbNeverDelete = sizeof(rgszNeverDelete) / sizeof(LPCTSTR*);
  127. inline BOOL CRegParser::VTFromRegType(LPCTSTR szValueType, VARTYPE& vt)
  128. {
  129.     struct typemap
  130.     {
  131.         LPCTSTR lpsz;
  132.         VARTYPE vt;
  133.     };
  134. #pragma warning (push)
  135. #pragma warning (disable : 4640)    // construction of local static object is not thread-safe
  136.     static const typemap map[] = {
  137.         {szStringVal, VT_BSTR},
  138.         {multiszStringVal, VT_BSTR | VT_BYREF},
  139.         {szDwordVal,  VT_UI4},
  140.         {szBinaryVal, VT_UI1}
  141.     };
  142. #pragma warning (pop)
  143.     for (int i=0;i<sizeof(map)/sizeof(typemap);i++)
  144.     {
  145.         if (!lstrcmpi(szValueType, map[i].lpsz))
  146.         {
  147.             vt = map[i].vt;
  148.             return TRUE;
  149.         }
  150.     }
  151.     return FALSE;
  152. }
  153. inline BYTE CRegParser::ChToByte(const TCHAR ch)
  154. {
  155.     switch (ch)
  156.     {
  157.         case '0':
  158.         case '1':
  159.         case '2':
  160.         case '3':
  161.         case '4':
  162.         case '5':
  163.         case '6':
  164.         case '7':
  165.         case '8':
  166.         case '9':
  167.                 return (BYTE) (ch - '0');
  168.         case 'A':
  169.         case 'B':
  170.         case 'C':
  171.         case 'D':
  172.         case 'E':
  173.         case 'F':
  174.                 return (BYTE) (10 + (ch - 'A'));
  175.         case 'a':
  176.         case 'b':
  177.         case 'c':
  178.         case 'd':
  179.         case 'e':
  180.         case 'f':
  181.                 return (BYTE) (10 + (ch - 'a'));
  182.         default:
  183.                 ATLASSERT(FALSE);
  184.                 ATLTRACE(atlTraceRegistrar, 0, _T("Bogus value %c passed as binary Hex value/n"), ch);
  185.                 return 0;
  186.     }
  187. }
  188. inline HKEY CRegParser::HKeyFromString(_In_z_ LPTSTR szToken)
  189. {
  190.     struct keymap
  191.     {
  192.         LPCTSTR lpsz;
  193.         HKEY hkey;
  194.     };
  195.     static const keymap map[] = {
  196.         {_T("HKCR"), HKEY_CLASSES_ROOT},
  197.         {_T("HKCU"), HKEY_CURRENT_USER},
  198.         {_T("HKLM"), HKEY_LOCAL_MACHINE},
  199.         {_T("HKU"),  HKEY_USERS},
  200.         {_T("HKPD"), HKEY_PERFORMANCE_DATA},
  201.         {_T("HKDD"), HKEY_DYN_DATA},
  202.         {_T("HKCC"), HKEY_CURRENT_CONFIG},
  203.         {_T("HKEY_CLASSES_ROOT"), HKEY_CLASSES_ROOT},
  204.         {_T("HKEY_CURRENT_USER"), HKEY_CURRENT_USER},
  205.         {_T("HKEY_LOCAL_MACHINE"), HKEY_LOCAL_MACHINE},
  206.         {_T("HKEY_USERS"), HKEY_USERS},
  207.         {_T("HKEY_PERFORMANCE_DATA"), HKEY_PERFORMANCE_DATA},
  208.         {_T("HKEY_DYN_DATA"), HKEY_DYN_DATA},
  209.         {_T("HKEY_CURRENT_CONFIG"), HKEY_CURRENT_CONFIG}
  210.     };
  211.     for (int i=0;i<sizeof(map)/sizeof(keymap);i++)
  212.     {
  213.         if (!lstrcmpi(szToken, map[i].lpsz))
  214.             return map[i].hkey;
  215.     }
  216.     return NULL;
  217. }
  218. inline LPTSTR CRegParser::StrChr(_In_z_ LPTSTR lpsz, _In_ TCHAR ch)
  219. {
  220.     LPTSTR p = NULL;
  221.     if (lpsz == NULL)
  222.         return NULL;
  223.     
  224.     while (*lpsz)
  225.     {
  226.         if (*lpsz == ch)
  227.         {
  228.             p = lpsz;
  229.             break;
  230.         }
  231.         lpsz = CharNext(lpsz);
  232.     }
  233.     return p;
  234. }
  235. inline CRegParser::CRegParser()
  236. {
  237.     m_pchCur = NULL;
  238. }
  239. inline BOOL CRegParser::IsSpace(TCHAR ch)
  240. {
  241.     switch (ch)
  242.     {
  243.         case _T(' '):
  244.         case _T('/t'):
  245.         case _T('/r'):
  246.         case _T('/n'):
  247.                 return TRUE;
  248.     }
  249.     return FALSE;
  250. }
  251. inline void CRegParser::SkipWhiteSpace()
  252. {
  253.     while(IsSpace(*m_pchCur))
  254.         m_pchCur = CharNext(m_pchCur);
  255. }
  256. #pragma warning(push)
  257. #pragma warning(disable:6385) // suppressing code analysis warning on the GenerateError code path
  258. inline HRESULT CRegParser::NextToken(_Out_z_cap_c_(MAX_VALUE) LPTSTR szToken)
  259. {
  260.     SkipWhiteSpace();
  261.     // NextToken cannot be called at EOS
  262.     if (NULL == *m_pchCur)
  263.         return GenerateError(E_ATL_UNEXPECTED_EOS);
  264. #pragma warning(pop)
  265.     LPCTSTR szOrig = szToken;
  266.     // handle quoted value / key
  267.     if (chQuote == *m_pchCur)
  268.     {
  269.         m_pchCur = CharNext(m_pchCur);
  270.         while (NULL != *m_pchCur && !EndOfVar())
  271.         {
  272.             if (chQuote == *m_pchCur) // If it is a quote that means we must skip it
  273.                 m_pchCur = CharNext(m_pchCur);
  274.             LPTSTR pchPrev = m_pchCur;
  275.             m_pchCur = CharNext(m_pchCur);
  276.             INT_PTR nChars = m_pchCur - pchPrev;
  277.             // Make sure we have room for nChars plus terminating NULL
  278.             if ((szToken + nChars + 1) >= szOrig + MAX_VALUE)
  279.                 return GenerateError(E_ATL_VALUE_TOO_LARGE);
  280.             for (int i = 0; i < (int)nChars; i++, szToken++, pchPrev++)
  281.                 *szToken = *pchPrev;
  282.         }
  283.         if (NULL == *m_pchCur)
  284.         {
  285.             ATLTRACE(atlTraceRegistrar, 0, _T("NextToken : Unexpected End of File/n"));
  286.             return GenerateError(E_ATL_UNEXPECTED_EOS);
  287.         }
  288.         *szToken = NULL;
  289.         m_pchCur = CharNext(m_pchCur);
  290.     }
  291.     else
  292.     {   
  293.         // Handle non-quoted ie parse up till first "White Space"
  294.         while (NULL != *m_pchCur && !IsSpace(*m_pchCur))
  295.         {
  296.             LPTSTR pchPrev = m_pchCur;
  297.             m_pchCur = CharNext(m_pchCur);
  298.             INT_PTR nChars = m_pchCur - pchPrev;
  299.             // Make sure we have room for nChars plus terminating NULL
  300.             if ((szToken + nChars + 1) >= szOrig + MAX_VALUE)
  301.                 return GenerateError(E_ATL_VALUE_TOO_LARGE);
  302.             for (int i = 0; i < (int)nChars; i++, szToken++, pchPrev++)
  303.                 *szToken = *pchPrev;
  304.         }
  305.         *szToken = NULL;
  306.     }
  307.     return S_OK;
  308. }
  309. #pragma warning(push)
  310. #pragma warning(disable:6385) // suppressing code analysis warning on the GenerateError code path
  311. inline HRESULT CRegParser::AddValue(_In_ CRegKey& rkParent, _In_opt_z_ LPCTSTR szValueName, _Out_z_cap_c_(MAX_VALUE) LPTSTR szToken)
  312. {
  313.     HRESULT hr;
  314.     TCHAR       szValue[MAX_VALUE];
  315.     VARTYPE     vt = VT_EMPTY;
  316.     LONG        lRes = ERROR_SUCCESS;
  317.     UINT        nIDRes = 0;
  318.     if (FAILED(hr = NextToken(szValue)))
  319.         return hr;
  320.     if (!VTFromRegType(szValue, vt))
  321.     {
  322.         ATLTRACE(atlTraceRegistrar, 0, _T("%s Type not supported/n"), szValue);
  323.         return GenerateError(E_ATL_TYPE_NOT_SUPPORTED);
  324.     }
  325. #pragma warning(pop)
  326.     SkipWhiteSpace();
  327.     if (FAILED(hr = NextToken(szValue)))
  328.         return hr;
  329.     switch (vt)
  330.     {
  331.     case VT_BSTR:
  332.         {
  333.             lRes = rkParent.SetStringValue(szValueName, szValue);
  334.             ATLTRACE(atlTraceRegistrar, 2, _T("Setting Value %s at %s/n"), szValue, !szValueName ? _T("default") : szValueName);
  335.             break;
  336.         }
  337.     case VT_BSTR | VT_BYREF:
  338.         {
  339.             ATLTRACE(atlTraceRegistrar, 2, _T("Setting Value %s at %s/n"), szValue, !szValueName ? _T("default") : szValueName);
  340.             int nLen = lstrlen(szValue) + 2; //Allocate space for double null termination.
  341.             CTempBuffer<TCHAR, 256> pszDestValue;
  342.             //nLen should be >= the max size of the target buffer.
  343.             ATLTRY(pszDestValue.Allocate(nLen));
  344.             if (pszDestValue != NULL)
  345.             {
  346.                 TCHAR* p = pszDestValue;
  347.                 TCHAR* q = szValue;
  348.                 nLen = 0;
  349.                 while (*q != _T('/0'))
  350.                 {
  351.                     TCHAR* r = CharNext(q);
  352.                     if (*q == _T('//') && *r == _T('0'))
  353.                     {
  354.                         *p++ = NULL;
  355.                         q = CharNext(r);
  356.                     }
  357.                     else
  358.                     {
  359.                         *p = *q;
  360. #ifndef _UNICODE
  361.                         if (IsDBCSLeadByte(*q))
  362.                         {
  363.                             p++;
  364.                             q++;
  365.                             //Protect from Lead byte followed by the zero terminator.May skip beyond the end of the string.
  366.                             if (*q == _T('/0')) { break; }
  367.                             *p = *q;
  368.                         }
  369. #endif
  370.                         p++;
  371.                         q++;
  372.                     }
  373.                     nLen ++;
  374.                 }
  375.                //Always terminate with 2 NULLs.
  376.                 *p = NULL;
  377.                 p++;
  378.                 *p = NULL;
  379.                 lRes = rkParent.SetMultiStringValue(szValueName, pszDestValue);
  380.             }
  381.             else
  382.             {
  383.                 lRes = ERROR_OUTOFMEMORY;
  384.             }
  385.         }
  386.         break;
  387.     case VT_UI4:
  388.         {
  389.             ULONG ulVal;
  390.             USES_CONVERSION_EX;
  391.             LPOLESTR lpszV = T2OLE_EX(szValue, _ATL_SAFE_ALLOCA_DEF_THRESHOLD);
  392.     #ifndef _UNICODE
  393.             if(lpszV == NULL) 
  394.                 return E_OUTOFMEMORY;
  395.     #endif  
  396.             VarUI4FromStr(lpszV, 0, 0, &ulVal);
  397.             
  398.             lRes = rkParent.SetDWORDValue(szValueName, ulVal);
  399.             ATLTRACE(atlTraceRegistrar, 2, _T("Setting Value %d at %s/n"), ulVal, !szValueName ? _T("default") : szValueName);
  400.             break;
  401.         }
  402.     case VT_UI1:
  403.         {
  404.             int cbValue = lstrlen(szValue);
  405.             if (cbValue & 0x00000001)
  406.             {
  407.                 ATLTRACE(atlTraceRegistrar, 0, _T("Binary Data does not fall on BYTE boundries/n"));
  408.                 return E_FAIL;
  409.             }
  410.             int cbValDiv2 = cbValue/2;
  411.             CTempBuffer<BYTE, 256> rgBinary;
  412.             ATLTRY(rgBinary.Allocate(cbValDiv2));           
  413.             if (rgBinary == NULL)
  414.                 return E_FAIL;
  415.             memset(rgBinary, 0, cbValDiv2);             
  416.             for (int irg = 0; irg < cbValue; irg++)
  417.                 rgBinary[(irg/2)] |= (ChToByte(szValue[irg])) << (4*(1 - (irg & 0x00000001)));
  418.             lRes = RegSetValueEx(rkParent, szValueName, 0, REG_BINARY, rgBinary, cbValDiv2);
  419.             break;
  420.         }
  421.     }
  422.     if (ERROR_SUCCESS != lRes)
  423.     {
  424.         nIDRes = E_ATL_VALUE_SET_FAILED;
  425.         return AtlHresultFromWin32(lRes);
  426.     }
  427.     if (FAILED(hr = NextToken(szToken)))
  428.         return hr;
  429.     return S_OK;
  430. }
  431. inline BOOL CRegParser::CanForceRemoveKey(LPCTSTR szKey)
  432. {
  433.     for (int iNoDel = 0; iNoDel < cbNeverDelete; iNoDel++)
  434.         if (!lstrcmpi(szKey, rgszNeverDelete[iNoDel]))
  435.              return FALSE;                       // We cannot delete it
  436.     return TRUE;
  437. }
  438. inline BOOL CRegParser::HasSubKeys(HKEY hkey)
  439. {
  440.     DWORD       cbSubKeys = 0;
  441.     if (RegQueryInfoKey(hkey, NULL, NULL, NULL,
  442.                                &cbSubKeys, NULL, NULL,
  443.                                NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
  444.     {
  445.         ATLTRACE(atlTraceRegistrar, 0, _T("Should not be here!!/n"));
  446.         ATLASSERT(FALSE);
  447.         return FALSE;
  448.     }
  449.     return cbSubKeys > 0;
  450. }
  451. inline BOOL CRegParser::HasValues(HKEY hkey)
  452. {
  453.     DWORD       cbValues = 0;
  454.     LONG lResult = RegQueryInfoKey(hkey, NULL, NULL, NULL,
  455.                                   NULL, NULL, NULL,
  456.                                   &cbValues, NULL, NULL, NULL, NULL);
  457.     if (ERROR_SUCCESS != lResult)
  458.     {
  459.         ATLTRACE(atlTraceRegistrar, 0, _T("RegQueryInfoKey Failed "));
  460.         ATLASSERT(FALSE);
  461.         return FALSE;
  462.     }
  463.     if (1 == cbValues)
  464.     {
  465.         DWORD cbMaxName= MAX_VALUE;
  466.         TCHAR szValueName[MAX_VALUE];
  467.         // Check to see if the Value is default or named
  468.         lResult = RegEnumValue(hkey, 0, szValueName, &cbMaxName, NULL, NULL, NULL, NULL);
  469.         if (ERROR_SUCCESS == lResult && (szValueName[0] != NULL))
  470.             return TRUE; // Named Value means we have a value
  471.         return FALSE;
  472.     }
  473.     return cbValues > 0; // More than 1 means we have a non-default value
  474. }
  475. inline HRESULT CRegParser::SkipAssignment(_Inout_z_cap_c_(MAX_VALUE) LPTSTR szToken)
  476. {
  477.     HRESULT hr;
  478.     TCHAR szValue[MAX_VALUE];
  479.     if (*szToken == chEquals)
  480.     {
  481.         if (FAILED(hr = NextToken(szToken)))
  482.             return hr;
  483.         // Skip assignment
  484.         SkipWhiteSpace();
  485.         if (FAILED(hr = NextToken(szValue)))
  486.             return hr;
  487.         if (FAILED(hr = NextToken(szToken)))
  488.             return hr;
  489.     }
  490.     return S_OK;
  491. }
  492. inline HRESULT CRegParser::PreProcessBuffer(_In_z_ LPTSTR lpszReg, _Deref_out_opt_z_ LPTSTR* ppszReg)
  493. {
  494.     ATLASSERT(lpszReg != NULL);
  495.     ATLASSERT(ppszReg != NULL);
  496.     if (lpszReg == NULL || ppszReg == NULL)
  497.         return E_POINTER;
  498.     
  499.     *ppszReg = NULL;
  500.     int nSize = lstrlen(lpszReg)*2;
  501.     CParseBuffer pb(nSize);
  502.     if (pb.p == NULL)
  503.         return E_OUTOFMEMORY;
  504.     m_pchCur = lpszReg;
  505.     HRESULT hr = S_OK;
  506.     bool bRedirectionEnabled = false;
  507.     hr = AtlGetPerUserRegistration(&bRedirectionEnabled);
  508.     if( FAILED(hr) )
  509.     {
  510.         return hr;
  511.     }
  512.     // nNestingLevel is used to avoid checking for unnecessary root key replacements
  513.     // since all of them are expected to be at the top level.
  514.     int nNestingLevel = 0;
  515.     bool bRedirectionPresent = false;
  516.     bool bInsideQuotes = false;
  517.     while (*m_pchCur != NULL) // look for end
  518.     {
  519.         if ( true == bRedirectionEnabled )
  520.         {
  521.             LPCOLESTR szStartHKCU = L"HKCU/r/n{/tSoftware/r/n/t{/r/n/t/tClasses";
  522.             LPCOLESTR szEndHKCU = L"/r/n/t}/r/n}/r/n";
  523.             if ( 0 == nNestingLevel )
  524.             {
  525.                 // Then we should be reading a root key. HKCR, HKCU, etc
  526.                 TCHAR* szRootKey = NULL;
  527.                 if( NULL != ( szRootKey = _tcsstr(m_pchCur, _T("HKCR")) ) &&    // if HKCR is found.
  528.                     (szRootKey == m_pchCur) )   // if HKCR is the first token.
  529.                 {
  530.                     // Skip HKCR
  531.                     m_pchCur = CharNext(m_pchCur);
  532.                     m_pchCur = CharNext(m_pchCur);
  533.                     m_pchCur = CharNext(m_pchCur);
  534.                     m_pchCur = CharNext(m_pchCur);
  535.                     // Add HKCU
  536.                     if (!pb.AddString(szStartHKCU))
  537.                     {
  538.                         hr = E_OUTOFMEMORY;
  539.                         break;
  540.                     }
  541.                     bRedirectionPresent = true;
  542.                 }
  543.             }
  544.             if ( chQuote == *m_pchCur )
  545.             {
  546.                 iffalse == bInsideQuotes )
  547.                 {
  548.                     bInsideQuotes = true;
  549.                 }
  550.                 else
  551.                 {
  552.                     // Make sure it is not an escaped sequence.
  553.                     if( EndOfVar() )
  554.                     {
  555.                         bInsideQuotes = false;
  556.                     }
  557.                     else
  558.                     {
  559.                         // An escaped single quote...
  560.                         m_pchCur = CharNext(m_pchCur);
  561.                         if (!pb.AddChar(m_pchCur))
  562.                         {
  563.                             hr = E_OUTOFMEMORY;
  564.                             break;
  565.                         }
  566.                     }
  567.                 }
  568.             }
  569.             if ( (false == bInsideQuotes) && (*m_pchCur == _T('{')) )
  570.             {
  571.                 ++nNestingLevel;
  572.             }
  573.             if ( (false == bInsideQuotes) && (*m_pchCur == _T('}')) )
  574.             {
  575.                 --nNestingLevel;
  576.                 if ( (0 == nNestingLevel) && (true == bRedirectionPresent) )
  577.                 {
  578.                     if (!pb.AddString(szEndHKCU))
  579.                     {
  580.                         hr = E_OUTOFMEMORY;
  581.                         break;
  582.                     }
  583.                     bRedirectionPresent = false;
  584.                 }
  585.             }
  586.         }
  587.         if (*m_pchCur == _T('%'))
  588.         {
  589.             m_pchCur = CharNext(m_pchCur);
  590.             if (*m_pchCur == _T('%'))
  591.             {
  592.                 if (!pb.AddChar(m_pchCur))
  593.                 {
  594.                     hr = E_OUTOFMEMORY;
  595.                     break;
  596.                 }
  597.             }
  598.             else
  599.             {
  600.                 LPTSTR lpszNext = StrChr(m_pchCur, _T('%'));
  601.                 if (lpszNext == NULL)
  602.                 {
  603.                     ATLTRACE(atlTraceRegistrar, 0, _T("Error no closing %% found/n"));
  604.                     hr = GenerateError(E_ATL_UNEXPECTED_EOS);
  605.                     break;
  606.                 }
  607.                 if ((lpszNext-m_pchCur) > 31)
  608.                 {
  609.                     hr = E_FAIL;
  610.                     break;
  611.                 }
  612.                 int nLength = int(lpszNext - m_pchCur);
  613.                 TCHAR buf[32];
  614.                 Checked::tcsncpy_s(buf, _countof(buf), m_pchCur, nLength);
  615.                 //LPCOLESTR lpszVar = m_pRegObj->StrFromMap(buf);
  616.                 //if (lpszVar == NULL)
  617.                 //{
  618.                 //  hr = GenerateError(E_ATL_NOT_IN_MAP);
  619.                 //  break;
  620.                 //}
  621.                 //if (!pb.AddString(lpszVar))
  622.                 //{
  623.                 //  hr = E_OUTOFMEMORY;
  624.                 //  break;
  625.                 //}
  626.                 while (m_pchCur != lpszNext)
  627.                     m_pchCur = CharNext(m_pchCur);
  628.             }
  629.         }
  630.         else
  631.         {
  632.             if (!pb.AddChar(m_pchCur))
  633.             {
  634.                 hr = E_OUTOFMEMORY;
  635.                 break

抱歉!评论已关闭.