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.

667 lines
17 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: olereg.cpp
  7. //
  8. // Contents: Helper routines to interrogate the reg database
  9. //
  10. // Classes:
  11. //
  12. // Functions: OleRegGetUserType
  13. // OleRegGetMiscStatus
  14. // OleGetAutoConvert
  15. // OleSetAutoConvert
  16. //
  17. // History: dd-mmm-yy Author Comment
  18. // 11-Jan-94 alexgo added VDATEHEAP macros to every function
  19. // 30-Nov-93 alexgo 32bit port
  20. // 11-Nov-92 jasonful author
  21. //
  22. //--------------------------------------------------------------------------
  23. #include <le2int.h>
  24. #pragma SEG(olereg)
  25. #include <reterr.h>
  26. #include "oleregpv.h"
  27. #include <ctype.h>
  28. ASSERTDATA
  29. #define MAX_STR 512
  30. // Reg Db Keys
  31. static const OLECHAR szAuxUserTypeKey[] = OLESTR("AuxUserType");
  32. static const OLECHAR szMiscStatusKey[] = OLESTR("MiscStatus") ;
  33. static const OLECHAR szProgIDKey[] = OLESTR("ProgID");
  34. static const OLECHAR szClsidKey[] = OLESTR("Clsid");
  35. static const OLECHAR szAutoConverTo[] = OLESTR("AutoConvertTo");
  36. // this is really a global variable
  37. const OLECHAR szClsidRoot[] = OLESTR("CLSID\\");
  38. static INTERNAL OleRegGetDword
  39. (HKEY hkey,
  40. LPCOLESTR szKey,
  41. DWORD FAR* pdw);
  42. static INTERNAL OleRegGetDword
  43. (HKEY hkey,
  44. DWORD dwKey,
  45. DWORD FAR* pdw);
  46. static INTERNAL OleRegGetString
  47. (HKEY hkey,
  48. LPCOLESTR szKey,
  49. LPOLESTR FAR* pszValue);
  50. static INTERNAL OleRegGetString
  51. (HKEY hkey,
  52. DWORD dwKey,
  53. LPOLESTR FAR* pszValue);
  54. //+-------------------------------------------------------------------------
  55. //
  56. // Function: Atol (static)
  57. //
  58. // Synopsis: Converts string to integer
  59. //
  60. // Effects:
  61. //
  62. // Arguments: [sz] -- the string
  63. //
  64. // Requires:
  65. //
  66. // Returns: LONG
  67. //
  68. // Signals:
  69. //
  70. // Modifies:
  71. //
  72. // Algorithm:
  73. //
  74. // History: dd-mmm-yy Author Comment
  75. // 30-Nov-93 alexgo 32bit port
  76. //
  77. // Notes: 32bit OLE just uses wcstol as a #define
  78. //
  79. // original 16bit comment:
  80. //
  81. // Replacement for stdlib atol,
  82. // which didn't work and doesn't take far pointers.
  83. // Must be tolerant of leading spaces.
  84. //
  85. //--------------------------------------------------------------------------
  86. #ifndef WIN32
  87. #pragma SEG(Atol)
  88. FARINTERNAL_(LONG) Atol
  89. (LPOLESTR sz)
  90. {
  91. VDATEHEAP();
  92. signed int sign = +1;
  93. UINT base = 10;
  94. LONG l = 0;
  95. if (NULL==sz)
  96. {
  97. Assert (0);
  98. return 0;
  99. }
  100. while (isspace(*sz))
  101. {
  102. sz++;
  103. }
  104. if (*sz== OLESTR('-'))
  105. {
  106. sz++;
  107. sign = -1;
  108. }
  109. if (sz[0]==OLESTR('0') && sz[1]==OLESTR('x'))
  110. {
  111. base = 16;
  112. sz+=2;
  113. }
  114. if (base==10)
  115. {
  116. while (isdigit(*sz))
  117. {
  118. l = l * base + *sz - OLESTR('0');
  119. sz++;
  120. }
  121. }
  122. else
  123. {
  124. Assert (base==16);
  125. while (isxdigit(*sz))
  126. {
  127. l = l * base + isdigit(*sz) ? *sz - OLESTR('0') :
  128. toupper(*sz) - OLESTR('A') + 10;
  129. sz++;
  130. }
  131. }
  132. return l * sign;
  133. }
  134. #endif //!WIN32
  135. //+-------------------------------------------------------------------------
  136. //
  137. // Function: OleRegGetDword
  138. //
  139. // Synopsis: returns the value of subkey "szKey" as a DWORD
  140. //
  141. // Effects:
  142. //
  143. // Arguments: [hkey] -- handle to a key in the regdb
  144. // [szKey] -- the subkey to look for
  145. // [pdw] -- where to put the dword
  146. //
  147. // Requires:
  148. //
  149. // Returns: HRESULT
  150. //
  151. // Signals:
  152. //
  153. // Modifies:
  154. //
  155. // Algorithm:
  156. //
  157. // History: dd-mmm-yy Author Comment
  158. // 30-Nov-93 alexgo 32bit port
  159. //
  160. // Notes:
  161. //
  162. //--------------------------------------------------------------------------
  163. #pragma SEG(OleRegGetDword)
  164. static INTERNAL OleRegGetDword
  165. (HKEY hkey,
  166. LPCOLESTR szKey,
  167. DWORD FAR* pdw)
  168. {
  169. VDATEHEAP();
  170. VDATEPTRIN (pdw, DWORD);
  171. LPOLESTR szLong = NULL;
  172. HRESULT hresult = OleRegGetString (hkey, szKey, &szLong);
  173. if (hresult != NOERROR)
  174. {
  175. return hresult;
  176. }
  177. *pdw = Atol (szLong);
  178. PubMemFree(szLong);
  179. return NOERROR;
  180. }
  181. //+-------------------------------------------------------------------------
  182. //
  183. // Function: OleRegGetDword (overloaded)
  184. //
  185. // Synopsis: Gets a dword from a sub-key given as a dword
  186. //
  187. // Effects:
  188. //
  189. // Arguments: [hkey] -- handle to a key in the regdb
  190. // [dwKey] -- number to convert to a string key to lookup in
  191. // the regdb
  192. // [pdw] -- where to put the dword
  193. //
  194. // Requires:
  195. //
  196. // Returns: HRESULT
  197. //
  198. // Signals:
  199. //
  200. // Modifies:
  201. //
  202. // Algorithm:
  203. //
  204. // History: dd-mmm-yy Author Comment
  205. // 30-Nov-93 alexgo 32bit port
  206. //
  207. // Notes: REVIEW32: This deep layering is kinda strange, as each
  208. // overloaded function is used exactly once. It might be
  209. // better just to inline the stuff and be done with it.
  210. //
  211. //--------------------------------------------------------------------------
  212. #pragma SEG(OleRegGetDword)
  213. static INTERNAL OleRegGetDword
  214. (HKEY hkey,
  215. DWORD dwKey,
  216. DWORD FAR* pdw)
  217. {
  218. VDATEHEAP();
  219. OLECHAR szBuf[MAX_STR];
  220. wsprintf(szBuf, OLESTR("%ld"), dwKey);
  221. return OleRegGetDword (hkey, szBuf, pdw);
  222. }
  223. //+-------------------------------------------------------------------------
  224. //
  225. // Function: OleRegGetString
  226. //
  227. // Synopsis: Return the value of subkey [szKey] of key [hkey] as a string
  228. //
  229. // Effects:
  230. //
  231. // Arguments: [hkey] -- a handle to a key in the reg db
  232. // [szKey] -- the subkey to get the value of
  233. // [ppszValue] -- where to put the value string
  234. //
  235. // Requires:
  236. //
  237. // Returns: HRESULT (NOERROR, E_OUTOFMEMORY, REGDB_E_KEYMISSING)
  238. //
  239. // Signals:
  240. //
  241. // Modifies:
  242. //
  243. // Algorithm:
  244. //
  245. // History: dd-mmm-yy Author Comment
  246. // 01-Dec-93 alexgo 32bit port
  247. // 15-Dec-93 ChrisWe cb is supposed to be the size of the
  248. // buffer in bytes; changed to use sizeof()
  249. //
  250. // Notes:
  251. //
  252. //--------------------------------------------------------------------------
  253. #pragma SEG(OleRegGetString)
  254. static INTERNAL OleRegGetString
  255. (HKEY hkey,
  256. LPCOLESTR szKey,
  257. LPOLESTR FAR* ppszValue)
  258. {
  259. VDATEHEAP();
  260. OLECHAR szBuf [MAX_STR];
  261. LONG cb = sizeof(szBuf);
  262. *ppszValue = NULL;
  263. if (ERROR_SUCCESS == RegQueryValue (hkey, (LPOLESTR) szKey,
  264. szBuf, &cb))
  265. {
  266. *ppszValue = UtDupString (szBuf);
  267. return *ppszValue ? NOERROR : ResultFromScode (E_OUTOFMEMORY);
  268. }
  269. return ReportResult(0, REGDB_E_KEYMISSING, 0, 0);
  270. }
  271. //+-------------------------------------------------------------------------
  272. //
  273. // Function: OleRegGetString (overloaded)
  274. //
  275. // Synopsis: Gets the string value of the DWORD subkey
  276. //
  277. // Effects:
  278. //
  279. // Arguments: [hkey] -- handle to a key in the regdb
  280. // [dwKey] -- the subkey value
  281. // [ppszValue] -- where to put the return value
  282. //
  283. // Requires:
  284. //
  285. // Returns: HRESULT
  286. //
  287. // Signals:
  288. //
  289. // Modifies:
  290. //
  291. // Algorithm:
  292. //
  293. // History: dd-mmm-yy Author Comment
  294. // 01-Dec-93 alexgo 32bit port
  295. //
  296. // Notes:
  297. //
  298. //--------------------------------------------------------------------------
  299. static INTERNAL OleRegGetString
  300. (HKEY hkey,
  301. DWORD dwKey,
  302. LPOLESTR FAR* ppszValue)
  303. {
  304. VDATEHEAP();
  305. OLECHAR szBuf[MAX_STR];
  306. wsprintf(szBuf, OLESTR("%ld"), dwKey);
  307. return OleRegGetString (hkey, szBuf, ppszValue);
  308. }
  309. //+-------------------------------------------------------------------------
  310. //
  311. // Function: OleRegGetUserType
  312. //
  313. // Synopsis: Returns the user type name for the class id.
  314. //
  315. // Effects:
  316. //
  317. // Arguments: [clsid] -- the class ID to look up
  318. // [dwFormOfType] -- flag indicating whether the fullname,
  319. // shortname, or app name is desired
  320. // [ppszUserType] -- where to put the type string
  321. //
  322. // Requires: returned string must be deleted
  323. //
  324. // Returns: HRESULT (NOERROR, OLE_E_CLSID)
  325. //
  326. // Signals:
  327. //
  328. // Modifies:
  329. //
  330. // Algorithm:
  331. //
  332. // History: dd-mmm-yy Author Comment
  333. // 01-Nov-93 alexgo 32bit port
  334. //
  335. // Notes:
  336. //
  337. //--------------------------------------------------------------------------
  338. #pragma SEG(OleRegGetUserType)
  339. STDAPI OleRegGetUserType
  340. (REFCLSID clsid,
  341. DWORD dwFormOfType, // as in IOleObject::GetUserType
  342. LPOLESTR FAR* ppszUserType) // out parm
  343. {
  344. OLETRACEIN((API_OleRegGetUserType, PARAMFMT("clsid= %I, dwFormOfType= %x, ppszUserType= %p"),
  345. &clsid, dwFormOfType, ppszUserType));
  346. VDATEHEAP();
  347. LPOLESTR pszTemp;
  348. HKEY hkeyClsid = NULL;
  349. HKEY hkeyAux = NULL;
  350. HRESULT hresult = NOERROR;
  351. VDATEPTROUT_LABEL (ppszUserType, LPOLESTR, safeRtn, hresult);
  352. *ppszUserType = NULL;
  353. ErrRtnH(CoOpenClassKey(clsid, FALSE, &hkeyClsid));
  354. if (dwFormOfType == USERCLASSTYPE_FULL ||
  355. ERROR_SUCCESS != RegOpenKey (hkeyClsid, szAuxUserTypeKey,
  356. &hkeyAux))
  357. {
  358. // use Main User Type Name (value of key CLSID(...))
  359. hresult = OleRegGetString(hkeyClsid, (LPOLESTR)NULL,
  360. &pszTemp);
  361. if (SUCCEEDED(hresult))
  362. {
  363. // If no user type string is registered under the class key,
  364. // OleRegGetString returns NOERROR and returns an empty string.
  365. // We need to check for this and return the appropriate error.
  366. if ( !pszTemp[0] )
  367. {
  368. PubMemFree(pszTemp);
  369. hresult = ResultFromScode(REGDB_E_INVALIDVALUE);
  370. goto errRtn;
  371. }
  372. *ppszUserType = pszTemp;
  373. }
  374. }
  375. else
  376. {
  377. // look under key AuxUserType
  378. if (NOERROR !=
  379. OleRegGetString (hkeyAux, dwFormOfType, ppszUserType)
  380. || NULL==*ppszUserType
  381. || '\0'==(*ppszUserType)[0])
  382. {
  383. // Couldn't find the particular FormOfType requested,
  384. // so use Full User Type Name (value of main
  385. // CLSID key), as per spec
  386. ErrRtnH (OleRegGetString (hkeyClsid, (LPOLESTR)NULL,
  387. ppszUserType));
  388. }
  389. }
  390. errRtn:
  391. CLOSE (hkeyClsid);
  392. CLOSE (hkeyAux);
  393. safeRtn:
  394. OLETRACEOUT((API_OleRegGetUserType, hresult));
  395. return hresult;
  396. }
  397. //+-------------------------------------------------------------------------
  398. //
  399. // Function: OleRegGetMiscStatus
  400. //
  401. // Synopsis: Retrieves misc status bits from the reg db
  402. //
  403. // Effects:
  404. //
  405. // Arguments: [clsid] -- the class ID
  406. // [dwAspect] -- specify the aspect (used in querrying
  407. // the reg db)
  408. // [pdwStatus] -- return to return the status bits
  409. //
  410. // Requires:
  411. //
  412. // Returns: HRESULT
  413. //
  414. // Signals:
  415. //
  416. // Modifies:
  417. //
  418. // Algorithm:
  419. //
  420. // History: dd-mmm-yy Author Comment
  421. // 01-Dec-93 alexgo 32bit port
  422. //
  423. // Notes: Uses default (0) is the MiscStatus key is missing
  424. //
  425. //--------------------------------------------------------------------------
  426. #pragma SEG(OleRegGetMiscStatus)
  427. STDAPI OleRegGetMiscStatus
  428. (REFCLSID clsid,
  429. DWORD dwAspect,
  430. DWORD FAR* pdwStatus)
  431. {
  432. OLETRACEIN((API_OleRegGetMiscStatus, PARAMFMT("clsid= %I, dwAspect= %x, pdwStatus= %p"),
  433. &clsid, dwAspect, pdwStatus));
  434. VDATEHEAP();
  435. HKEY hkeyClsid = NULL;
  436. HKEY hkeyMisc = NULL;
  437. HRESULT hresult = NOERROR;
  438. VDATEPTROUT_LABEL(pdwStatus, DWORD, safeRtn, hresult);
  439. *pdwStatus = 0;
  440. ErrRtnH(CoOpenClassKey(clsid, FALSE, &hkeyClsid));
  441. // Open MiscStatus key
  442. if (ERROR_SUCCESS != RegOpenKey (hkeyClsid, szMiscStatusKey,
  443. &hkeyMisc))
  444. {
  445. // MiscStatus key not there, so use default.
  446. hresult = NOERROR;
  447. goto errRtn;
  448. }
  449. if (OleRegGetDword (hkeyMisc, dwAspect, pdwStatus) != NOERROR)
  450. {
  451. // Get default value from main Misc key
  452. ErrRtnH (OleRegGetDword (hkeyMisc,
  453. (LPOLESTR)NULL, pdwStatus));
  454. // Got default value
  455. }
  456. // Got value for dwAspect
  457. errRtn:
  458. CLOSE (hkeyMisc);
  459. CLOSE (hkeyClsid);
  460. safeRtn:
  461. OLETRACEOUT((API_OleRegGetMiscStatus, hresult));
  462. return hresult;
  463. }
  464. //+-------------------------------------------------------------------------
  465. //
  466. // Function: OleGetAutoConvert
  467. //
  468. // Synopsis: Retrieves the class ID that [clsidOld] should be converted
  469. // to via auto convert
  470. //
  471. // Effects:
  472. //
  473. // Arguments: [clsidOld] -- the original class ID
  474. // [pClsidNew] -- where to put the new convert-to class ID
  475. //
  476. // Requires:
  477. //
  478. // Returns: HRESULT
  479. //
  480. // Signals:
  481. //
  482. // Modifies:
  483. //
  484. // Algorithm:
  485. //
  486. // History: dd-mmm-yy Author Comment
  487. // 05-Apr-94 kevinro removed bogus assert, restructured
  488. // 01-Dec-93 alexgo 32bit port
  489. //
  490. // Notes:
  491. //
  492. //--------------------------------------------------------------------------
  493. #pragma SEG(OleGetAutoConvert)
  494. STDAPI OleGetAutoConvert(REFCLSID clsidOld, LPCLSID pClsidNew)
  495. {
  496. OLETRACEIN((API_OleGetAutoConvert, PARAMFMT("clsidOld= %I, pClsidNew= %p"),
  497. &clsidOld, pClsidNew));
  498. VDATEHEAP();
  499. HRESULT hresult;
  500. HKEY hkeyClsid = NULL;
  501. LPOLESTR lpszClsid = NULL;
  502. VDATEPTROUT_LABEL (pClsidNew, CLSID, errRtn, hresult);
  503. *pClsidNew = CLSID_NULL;
  504. hresult = CoOpenClassKey(clsidOld, FALSE, &hkeyClsid);
  505. if (FAILED(hresult))
  506. {
  507. goto errRtn;
  508. }
  509. hresult = OleRegGetString(hkeyClsid, szAutoConverTo, &lpszClsid);
  510. if (SUCCEEDED(hresult))
  511. {
  512. // Its Possible there is an AutoConvert Key under the CLSID but it has not value
  513. if (OLESTR('\0') == lpszClsid[0])
  514. {
  515. hresult = REGDB_E_KEYMISSING;
  516. }
  517. else
  518. {
  519. // convert string into CLSID
  520. hresult = CLSIDFromString(lpszClsid, pClsidNew);
  521. }
  522. }
  523. CLOSE(hkeyClsid);
  524. PubMemFree(lpszClsid);
  525. errRtn:
  526. OLETRACEOUT((API_OleGetAutoConvert, hresult));
  527. return hresult;
  528. }
  529. //+-------------------------------------------------------------------------
  530. //
  531. // Function: OleSetAutoConvert
  532. //
  533. // Synopsis: Sets the autoconvert information in the regdb
  534. //
  535. // Effects:
  536. //
  537. // Arguments: [clsidOld] -- the original class id
  538. // [clsidNew] -- that class id that [clsidOld] should be
  539. // auto-converted to
  540. //
  541. // Requires:
  542. //
  543. // Returns: HRESULT
  544. //
  545. // Signals:
  546. //
  547. // Modifies:
  548. //
  549. // Algorithm:
  550. //
  551. // History: dd-mmm-yy Author Comment
  552. // 01-Dec-93 alexgo 32bit port
  553. //
  554. // Notes:
  555. //
  556. //--------------------------------------------------------------------------
  557. #pragma SEG(OleSetAutoConvert)
  558. STDAPI OleSetAutoConvert(REFCLSID clsidOld, REFCLSID clsidNew)
  559. {
  560. OLETRACEIN((API_OleSetAutoConvert, PARAMFMT("clsidOld= %I, clsidNew= %I"),
  561. &clsidOld, &clsidNew));
  562. VDATEHEAP();
  563. HRESULT hresult;
  564. HKEY hkeyClsid = NULL;
  565. ErrRtnH(CoOpenClassKey(clsidOld, TRUE, &hkeyClsid));
  566. if (IsEqualCLSID(clsidNew, CLSID_NULL))
  567. {
  568. // ignore error since there may not be a value at present
  569. (void)RegDeleteKey(hkeyClsid, szAutoConverTo);
  570. }
  571. else
  572. {
  573. OLECHAR szClsid[MAX_STR];
  574. Verify(StringFromCLSID2(clsidNew, szClsid, sizeof(szClsid))
  575. != 0);
  576. if (RegSetValue(hkeyClsid, szAutoConverTo, REG_SZ, szClsid,
  577. _xstrlen(szClsid)) != ERROR_SUCCESS)
  578. {
  579. hresult = ResultFromScode(REGDB_E_WRITEREGDB);
  580. }
  581. }
  582. errRtn:
  583. CLOSE(hkeyClsid);
  584. OLETRACEOUT((API_OleSetAutoConvert, hresult));
  585. return hresult;
  586. }