Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

554 lines
13 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1994-1995 **
  4. //*********************************************************************
  5. //
  6. // CLSUTIL.C - some small, useful C++ classes to wrap memory allocation,
  7. // registry access, etc.
  8. //
  9. // HISTORY:
  10. //
  11. // 12/07/94 jeremys Borrowed from WNET common library
  12. //
  13. #include "inetcplp.h"
  14. #define DECL_CRTFREE
  15. #include <crtfree.h>
  16. BOOL BUFFER::Alloc( UINT cbBuffer )
  17. {
  18. _lpBuffer = (LPTSTR)::GlobalAlloc(GPTR,cbBuffer);
  19. if (_lpBuffer != NULL) {
  20. _cb = cbBuffer;
  21. return TRUE;
  22. }
  23. return FALSE;
  24. }
  25. BOOL BUFFER::Realloc( UINT cbNew )
  26. {
  27. LPVOID lpNew = ::GlobalReAlloc((HGLOBAL)_lpBuffer, cbNew,
  28. GMEM_MOVEABLE | GMEM_ZEROINIT);
  29. if (lpNew == NULL)
  30. return FALSE;
  31. _lpBuffer = (LPTSTR)lpNew;
  32. _cb = cbNew;
  33. return TRUE;
  34. }
  35. BUFFER::BUFFER( UINT cbInitial /* =0 */ )
  36. : BUFFER_BASE(),
  37. _lpBuffer( NULL )
  38. {
  39. if (cbInitial)
  40. Alloc( cbInitial );
  41. }
  42. BUFFER::~BUFFER()
  43. {
  44. if (_lpBuffer != NULL) {
  45. GlobalFree((HGLOBAL) _lpBuffer);
  46. _lpBuffer = NULL;
  47. }
  48. }
  49. BOOL BUFFER::Resize( UINT cbNew )
  50. {
  51. BOOL fSuccess;
  52. if (QuerySize() == 0)
  53. fSuccess = Alloc( cbNew );
  54. else {
  55. fSuccess = Realloc( cbNew );
  56. }
  57. if (fSuccess)
  58. _cb = cbNew;
  59. return fSuccess;
  60. }
  61. RegEntry::RegEntry(const TCHAR *pszSubKey, HKEY hkey, REGSAM regsam)
  62. {
  63. _error = RegCreateKeyEx(hkey, pszSubKey, 0, NULL, 0, regsam, NULL, &_hkey, NULL);
  64. if (_error) {
  65. bhkeyValid = FALSE;
  66. }
  67. else {
  68. bhkeyValid = TRUE;
  69. }
  70. }
  71. RegEntry::~RegEntry()
  72. {
  73. if (bhkeyValid) {
  74. RegCloseKey(_hkey);
  75. }
  76. }
  77. long RegEntry::SetValue(const TCHAR *pszValue, const TCHAR *string)
  78. {
  79. if (bhkeyValid) {
  80. _error = RegSetValueEx(_hkey, pszValue, 0, REG_SZ,
  81. (LPBYTE)string, (lstrlen(string)+1)*sizeof(TCHAR));
  82. }
  83. return _error;
  84. }
  85. long RegEntry::SetValue(const TCHAR *pszValue, unsigned long dwNumber)
  86. {
  87. if (bhkeyValid) {
  88. _error = RegSetValueEx(_hkey, pszValue, 0, REG_BINARY,
  89. (LPBYTE)&dwNumber, sizeof(dwNumber));
  90. }
  91. return _error;
  92. }
  93. long RegEntry::DeleteValue(const TCHAR *pszValue)
  94. {
  95. if (bhkeyValid) {
  96. _error = RegDeleteValue(_hkey, (LPTSTR) pszValue);
  97. }
  98. return _error;
  99. }
  100. TCHAR *RegEntry::GetString(const TCHAR *pszValue, TCHAR *string, unsigned long length)
  101. {
  102. DWORD dwType;
  103. if (bhkeyValid) {
  104. _error = RegQueryValueEx(_hkey, (LPTSTR) pszValue, 0, &dwType, (LPBYTE)string,
  105. &length);
  106. }
  107. if (_error) {
  108. *string = '\0';
  109. return NULL;
  110. }
  111. return string;
  112. }
  113. long RegEntry::GetNumber(const TCHAR *pszValue, long dwDefault)
  114. {
  115. DWORD dwType;
  116. long dwNumber = 0L;
  117. DWORD dwSize = sizeof(dwNumber);
  118. if (bhkeyValid) {
  119. _error = RegQueryValueEx(_hkey, (LPTSTR) pszValue, 0, &dwType, (LPBYTE)&dwNumber,
  120. &dwSize);
  121. }
  122. if (_error)
  123. dwNumber = dwDefault;
  124. return dwNumber;
  125. }
  126. long RegEntry::MoveToSubKey(const TCHAR *pszSubKeyName)
  127. {
  128. HKEY _hNewKey;
  129. if (bhkeyValid) {
  130. _error = RegOpenKeyEx ( _hkey,
  131. pszSubKeyName,
  132. 0,
  133. KEY_READ|KEY_WRITE,
  134. &_hNewKey );
  135. if (_error == ERROR_SUCCESS) {
  136. RegCloseKey(_hkey);
  137. _hkey = _hNewKey;
  138. }
  139. }
  140. return _error;
  141. }
  142. long RegEntry::FlushKey()
  143. {
  144. if (bhkeyValid) {
  145. _error = RegFlushKey(_hkey);
  146. }
  147. return _error;
  148. }
  149. RegEnumValues::RegEnumValues(RegEntry *pReqRegEntry)
  150. : pRegEntry(pReqRegEntry),
  151. iEnum(0),
  152. pchName(NULL),
  153. pbValue(NULL)
  154. {
  155. _error = pRegEntry->GetError();
  156. if (_error == ERROR_SUCCESS) {
  157. _error = RegQueryInfoKey ( pRegEntry->GetKey(), // Key
  158. NULL, // Buffer for class string
  159. NULL, // Size of class string buffer
  160. NULL, // Reserved
  161. NULL, // Number of subkeys
  162. NULL, // Longest subkey name
  163. NULL, // Longest class string
  164. &cEntries, // Number of value entries
  165. &cMaxValueName, // Longest value name
  166. &cMaxData, // Longest value data
  167. NULL, // Security descriptor
  168. NULL ); // Last write time
  169. }
  170. if (_error == ERROR_SUCCESS) {
  171. if (cEntries != 0) {
  172. cMaxValueName = cMaxValueName + 1; // REG_SZ needs one more for null
  173. cMaxData = cMaxData + 1; // REG_SZ needs one more for null
  174. pchName = new TCHAR[cMaxValueName];
  175. if (!pchName) {
  176. _error = ERROR_NOT_ENOUGH_MEMORY;
  177. }
  178. else {
  179. if (cMaxData) {
  180. pbValue = new BYTE[cMaxData];
  181. if (!pbValue) {
  182. _error = ERROR_NOT_ENOUGH_MEMORY;
  183. }
  184. }
  185. }
  186. }
  187. }
  188. }
  189. RegEnumValues::~RegEnumValues()
  190. {
  191. delete pchName;
  192. delete pbValue;
  193. }
  194. long RegEnumValues::Next()
  195. {
  196. if (_error != ERROR_SUCCESS) {
  197. return _error;
  198. }
  199. if (cEntries == iEnum) {
  200. return ERROR_NO_MORE_ITEMS;
  201. }
  202. DWORD cchName = cMaxValueName;
  203. dwDataLength = cMaxData;
  204. _error = RegEnumValue ( pRegEntry->GetKey(), // Key
  205. iEnum, // Index of value
  206. pchName, // Address of buffer for value name
  207. &cchName, // Address for size of buffer
  208. NULL, // Reserved
  209. &dwType, // Data type
  210. pbValue, // Address of buffer for value data
  211. &dwDataLength ); // Address for size of data
  212. iEnum++;
  213. return _error;
  214. }
  215. //////////////////////////////////////////////////////////////////////////////
  216. //
  217. // CAccessibleWrapper implementation
  218. //
  219. //////////////////////////////////////////////////////////////////////////////
  220. CAccessibleWrapper::CAccessibleWrapper( IAccessible * pAcc )
  221. : m_ref( 1 ),
  222. m_pAcc( pAcc ),
  223. m_pEnumVar( NULL ),
  224. m_pOleWin( NULL )
  225. {
  226. m_pAcc->AddRef();
  227. }
  228. CAccessibleWrapper::~CAccessibleWrapper()
  229. {
  230. m_pAcc->Release();
  231. if( m_pEnumVar )
  232. m_pEnumVar->Release();
  233. if( m_pOleWin )
  234. m_pOleWin->Release();
  235. }
  236. // IUnknown
  237. // Implement refcounting ourselves
  238. // Also implement QI ourselves, so that we return a ptr back to the wrapper.
  239. STDMETHODIMP CAccessibleWrapper::QueryInterface(REFIID riid, void** ppv)
  240. {
  241. HRESULT hr;
  242. *ppv = NULL;
  243. if ((riid == IID_IUnknown) ||
  244. (riid == IID_IDispatch) ||
  245. (riid == IID_IAccessible))
  246. {
  247. *ppv = (IAccessible *) this;
  248. }
  249. else if( riid == IID_IEnumVARIANT )
  250. {
  251. // Get the IEnumVariant from the object we are sub-classing so we can delegate
  252. // calls.
  253. if( ! m_pEnumVar )
  254. {
  255. hr = m_pAcc->QueryInterface( IID_IEnumVARIANT, (void **) & m_pEnumVar );
  256. if( FAILED( hr ) )
  257. {
  258. m_pEnumVar = NULL;
  259. return hr;
  260. }
  261. // Paranoia (in case QI returns S_OK with NULL...)
  262. if( ! m_pEnumVar )
  263. return E_NOINTERFACE;
  264. }
  265. *ppv = (IEnumVARIANT *) this;
  266. }
  267. else if( riid == IID_IOleWindow )
  268. {
  269. // Get the IOleWindow from the object we are sub-classing so we can delegate
  270. // calls.
  271. if( ! m_pOleWin )
  272. {
  273. hr = m_pAcc->QueryInterface( IID_IOleWindow, (void **) & m_pOleWin );
  274. if( FAILED( hr ) )
  275. {
  276. m_pOleWin = NULL;
  277. return hr;
  278. }
  279. // Paranoia (in case QI returns S_OK with NULL...)
  280. if( ! m_pOleWin )
  281. return E_NOINTERFACE;
  282. }
  283. *ppv = (IOleWindow*) this;
  284. }
  285. else
  286. return(E_NOINTERFACE);
  287. AddRef();
  288. return(NOERROR);
  289. }
  290. STDMETHODIMP_(ULONG) CAccessibleWrapper::AddRef()
  291. {
  292. return ++m_ref;
  293. }
  294. STDMETHODIMP_(ULONG) CAccessibleWrapper::Release()
  295. {
  296. ULONG ulRet = --m_ref;
  297. if( ulRet == 0 )
  298. delete this;
  299. return ulRet;
  300. }
  301. // IDispatch
  302. // - pass all through m_pAcc
  303. STDMETHODIMP CAccessibleWrapper::GetTypeInfoCount(UINT* pctinfo)
  304. {
  305. return m_pAcc->GetTypeInfoCount(pctinfo);
  306. }
  307. STDMETHODIMP CAccessibleWrapper::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
  308. {
  309. return m_pAcc->GetTypeInfo(itinfo, lcid, pptinfo);
  310. }
  311. STDMETHODIMP CAccessibleWrapper::GetIDsOfNames(REFIID riid, OLECHAR** rgszNames, UINT cNames,
  312. LCID lcid, DISPID* rgdispid)
  313. {
  314. return m_pAcc->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
  315. }
  316. STDMETHODIMP CAccessibleWrapper::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
  317. DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo,
  318. UINT* puArgErr)
  319. {
  320. return m_pAcc->Invoke(dispidMember, riid, lcid, wFlags,
  321. pdispparams, pvarResult, pexcepinfo,
  322. puArgErr);
  323. }
  324. // IAccessible
  325. // - pass all through m_pAcc
  326. STDMETHODIMP CAccessibleWrapper::get_accParent(IDispatch ** ppdispParent)
  327. {
  328. return m_pAcc->get_accParent(ppdispParent);
  329. }
  330. STDMETHODIMP CAccessibleWrapper::get_accChildCount(long* pChildCount)
  331. {
  332. return m_pAcc->get_accChildCount(pChildCount);
  333. }
  334. STDMETHODIMP CAccessibleWrapper::get_accChild(VARIANT varChild, IDispatch ** ppdispChild)
  335. {
  336. return m_pAcc->get_accChild(varChild, ppdispChild);
  337. }
  338. STDMETHODIMP CAccessibleWrapper::get_accName(VARIANT varChild, BSTR* pszName)
  339. {
  340. return m_pAcc->get_accName(varChild, pszName);
  341. }
  342. STDMETHODIMP CAccessibleWrapper::get_accValue(VARIANT varChild, BSTR* pszValue)
  343. {
  344. return m_pAcc->get_accValue(varChild, pszValue);
  345. }
  346. STDMETHODIMP CAccessibleWrapper::get_accDescription(VARIANT varChild, BSTR* pszDescription)
  347. {
  348. return m_pAcc->get_accDescription(varChild, pszDescription);
  349. }
  350. STDMETHODIMP CAccessibleWrapper::get_accRole(VARIANT varChild, VARIANT *pvarRole)
  351. {
  352. return m_pAcc->get_accRole(varChild, pvarRole);
  353. }
  354. STDMETHODIMP CAccessibleWrapper::get_accState(VARIANT varChild, VARIANT *pvarState)
  355. {
  356. return m_pAcc->get_accState(varChild, pvarState);
  357. }
  358. STDMETHODIMP CAccessibleWrapper::get_accHelp(VARIANT varChild, BSTR* pszHelp)
  359. {
  360. return m_pAcc->get_accHelp(varChild, pszHelp);
  361. }
  362. STDMETHODIMP CAccessibleWrapper::get_accHelpTopic(BSTR* pszHelpFile, VARIANT varChild, long* pidTopic)
  363. {
  364. return m_pAcc->get_accHelpTopic(pszHelpFile, varChild, pidTopic);
  365. }
  366. STDMETHODIMP CAccessibleWrapper::get_accKeyboardShortcut(VARIANT varChild, BSTR* pszKeyboardShortcut)
  367. {
  368. return m_pAcc->get_accKeyboardShortcut(varChild, pszKeyboardShortcut);
  369. }
  370. STDMETHODIMP CAccessibleWrapper::get_accFocus(VARIANT * pvarFocusChild)
  371. {
  372. return m_pAcc->get_accFocus(pvarFocusChild);
  373. }
  374. STDMETHODIMP CAccessibleWrapper::get_accSelection(VARIANT * pvarSelectedChildren)
  375. {
  376. return m_pAcc->get_accSelection(pvarSelectedChildren);
  377. }
  378. STDMETHODIMP CAccessibleWrapper::get_accDefaultAction(VARIANT varChild, BSTR* pszDefaultAction)
  379. {
  380. return m_pAcc->get_accDefaultAction(varChild, pszDefaultAction);
  381. }
  382. STDMETHODIMP CAccessibleWrapper::accSelect(long flagsSel, VARIANT varChild)
  383. {
  384. return m_pAcc->accSelect(flagsSel, varChild);
  385. }
  386. STDMETHODIMP CAccessibleWrapper::accLocation(long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varChild)
  387. {
  388. return m_pAcc->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varChild);
  389. }
  390. STDMETHODIMP CAccessibleWrapper::accNavigate(long navDir, VARIANT varStart, VARIANT * pvarEndUpAt)
  391. {
  392. return m_pAcc->accNavigate(navDir, varStart, pvarEndUpAt);
  393. }
  394. STDMETHODIMP CAccessibleWrapper::accHitTest(long xLeft, long yTop, VARIANT * pvarChildAtPoint)
  395. {
  396. return m_pAcc->accHitTest(xLeft, yTop, pvarChildAtPoint);
  397. }
  398. STDMETHODIMP CAccessibleWrapper::accDoDefaultAction(VARIANT varChild)
  399. {
  400. return m_pAcc->accDoDefaultAction(varChild);
  401. }
  402. STDMETHODIMP CAccessibleWrapper::put_accName(VARIANT varChild, BSTR szName)
  403. {
  404. return m_pAcc->put_accName(varChild, szName);
  405. }
  406. STDMETHODIMP CAccessibleWrapper::put_accValue(VARIANT varChild, BSTR pszValue)
  407. {
  408. return m_pAcc->put_accValue(varChild, pszValue);
  409. }
  410. // IEnumVARIANT
  411. // - pass all through m_pEnumVar
  412. STDMETHODIMP CAccessibleWrapper::Next(ULONG celt, VARIANT* rgvar, ULONG * pceltFetched)
  413. {
  414. return m_pEnumVar->Next(celt, rgvar, pceltFetched);
  415. }
  416. STDMETHODIMP CAccessibleWrapper::Skip(ULONG celt)
  417. {
  418. return m_pEnumVar->Skip(celt);
  419. }
  420. STDMETHODIMP CAccessibleWrapper::Reset()
  421. {
  422. return m_pEnumVar->Reset();
  423. }
  424. STDMETHODIMP CAccessibleWrapper::Clone(IEnumVARIANT ** ppenum)
  425. {
  426. return m_pEnumVar->Clone(ppenum);
  427. }
  428. // IOleWindow
  429. // - pass all through m_pOleWin
  430. STDMETHODIMP CAccessibleWrapper::GetWindow(HWND* phwnd)
  431. {
  432. return m_pOleWin->GetWindow(phwnd);
  433. }
  434. STDMETHODIMP CAccessibleWrapper::ContextSensitiveHelp(BOOL fEnterMode)
  435. {
  436. return m_pOleWin->ContextSensitiveHelp(fEnterMode);
  437. }