Leaked source code of windows server 2003
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.

665 lines
18 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 != RegOpenKeyEx (hkeyClsid, szAuxUserTypeKey, 0, KEY_READ, &hkeyAux))
  356. {
  357. // use Main User Type Name (value of key CLSID(...))
  358. hresult = OleRegGetString(hkeyClsid, (LPOLESTR)NULL,
  359. &pszTemp);
  360. if (SUCCEEDED(hresult))
  361. {
  362. // If no user type string is registered under the class key,
  363. // OleRegGetString returns NOERROR and returns an empty string.
  364. // We need to check for this and return the appropriate error.
  365. if ( !pszTemp[0] )
  366. {
  367. PubMemFree(pszTemp);
  368. hresult = ResultFromScode(REGDB_E_INVALIDVALUE);
  369. goto errRtn;
  370. }
  371. *ppszUserType = pszTemp;
  372. }
  373. }
  374. else
  375. {
  376. // look under key AuxUserType
  377. if (NOERROR !=
  378. OleRegGetString (hkeyAux, dwFormOfType, ppszUserType)
  379. || NULL==*ppszUserType
  380. || '\0'==(*ppszUserType)[0])
  381. {
  382. // Couldn't find the particular FormOfType requested,
  383. // so use Full User Type Name (value of main
  384. // CLSID key), as per spec
  385. ErrRtnH (OleRegGetString (hkeyClsid, (LPOLESTR)NULL,
  386. ppszUserType));
  387. }
  388. }
  389. errRtn:
  390. CLOSE (hkeyClsid);
  391. CLOSE (hkeyAux);
  392. safeRtn:
  393. OLETRACEOUT((API_OleRegGetUserType, hresult));
  394. return hresult;
  395. }
  396. //+-------------------------------------------------------------------------
  397. //
  398. // Function: OleRegGetMiscStatus
  399. //
  400. // Synopsis: Retrieves misc status bits from the reg db
  401. //
  402. // Effects:
  403. //
  404. // Arguments: [clsid] -- the class ID
  405. // [dwAspect] -- specify the aspect (used in querrying
  406. // the reg db)
  407. // [pdwStatus] -- return to return the status bits
  408. //
  409. // Requires:
  410. //
  411. // Returns: HRESULT
  412. //
  413. // Signals:
  414. //
  415. // Modifies:
  416. //
  417. // Algorithm:
  418. //
  419. // History: dd-mmm-yy Author Comment
  420. // 01-Dec-93 alexgo 32bit port
  421. //
  422. // Notes: Uses default (0) is the MiscStatus key is missing
  423. //
  424. //--------------------------------------------------------------------------
  425. #pragma SEG(OleRegGetMiscStatus)
  426. STDAPI OleRegGetMiscStatus
  427. (REFCLSID clsid,
  428. DWORD dwAspect,
  429. DWORD FAR* pdwStatus)
  430. {
  431. OLETRACEIN((API_OleRegGetMiscStatus, PARAMFMT("clsid= %I, dwAspect= %x, pdwStatus= %p"),
  432. &clsid, dwAspect, pdwStatus));
  433. VDATEHEAP();
  434. HKEY hkeyClsid = NULL;
  435. HKEY hkeyMisc = NULL;
  436. HRESULT hresult = NOERROR;
  437. VDATEPTROUT_LABEL(pdwStatus, DWORD, safeRtn, hresult);
  438. *pdwStatus = 0;
  439. ErrRtnH(CoOpenClassKey(clsid, FALSE, &hkeyClsid));
  440. // Open MiscStatus key
  441. if (ERROR_SUCCESS != RegOpenKeyEx (hkeyClsid, szMiscStatusKey, 0, KEY_READ, &hkeyMisc))
  442. {
  443. // MiscStatus key not there, so use default.
  444. hresult = NOERROR;
  445. goto errRtn;
  446. }
  447. if (OleRegGetDword (hkeyMisc, dwAspect, pdwStatus) != NOERROR)
  448. {
  449. // Get default value from main Misc key
  450. ErrRtnH (OleRegGetDword (hkeyMisc,
  451. (LPOLESTR)NULL, pdwStatus));
  452. // Got default value
  453. }
  454. // Got value for dwAspect
  455. errRtn:
  456. CLOSE (hkeyMisc);
  457. CLOSE (hkeyClsid);
  458. safeRtn:
  459. OLETRACEOUT((API_OleRegGetMiscStatus, hresult));
  460. return hresult;
  461. }
  462. //+-------------------------------------------------------------------------
  463. //
  464. // Function: OleGetAutoConvert
  465. //
  466. // Synopsis: Retrieves the class ID that [clsidOld] should be converted
  467. // to via auto convert
  468. //
  469. // Effects:
  470. //
  471. // Arguments: [clsidOld] -- the original class ID
  472. // [pClsidNew] -- where to put the new convert-to class ID
  473. //
  474. // Requires:
  475. //
  476. // Returns: HRESULT
  477. //
  478. // Signals:
  479. //
  480. // Modifies:
  481. //
  482. // Algorithm:
  483. //
  484. // History: dd-mmm-yy Author Comment
  485. // 05-Apr-94 kevinro removed bogus assert, restructured
  486. // 01-Dec-93 alexgo 32bit port
  487. //
  488. // Notes:
  489. //
  490. //--------------------------------------------------------------------------
  491. #pragma SEG(OleGetAutoConvert)
  492. STDAPI OleGetAutoConvert(REFCLSID clsidOld, LPCLSID pClsidNew)
  493. {
  494. OLETRACEIN((API_OleGetAutoConvert, PARAMFMT("clsidOld= %I, pClsidNew= %p"),
  495. &clsidOld, pClsidNew));
  496. VDATEHEAP();
  497. HRESULT hresult;
  498. HKEY hkeyClsid = NULL;
  499. LPOLESTR lpszClsid = NULL;
  500. VDATEPTROUT_LABEL (pClsidNew, CLSID, errRtn, hresult);
  501. *pClsidNew = CLSID_NULL;
  502. hresult = CoOpenClassKey(clsidOld, FALSE, &hkeyClsid);
  503. if (FAILED(hresult))
  504. {
  505. goto errRtn;
  506. }
  507. hresult = OleRegGetString(hkeyClsid, szAutoConverTo, &lpszClsid);
  508. if (SUCCEEDED(hresult))
  509. {
  510. // Its Possible there is an AutoConvert Key under the CLSID but it has not value
  511. if (OLESTR('\0') == lpszClsid[0])
  512. {
  513. hresult = REGDB_E_KEYMISSING;
  514. }
  515. else
  516. {
  517. // convert string into CLSID
  518. hresult = CLSIDFromString(lpszClsid, pClsidNew);
  519. }
  520. }
  521. CLOSE(hkeyClsid);
  522. PubMemFree(lpszClsid);
  523. errRtn:
  524. OLETRACEOUT((API_OleGetAutoConvert, hresult));
  525. return hresult;
  526. }
  527. //+-------------------------------------------------------------------------
  528. //
  529. // Function: OleSetAutoConvert
  530. //
  531. // Synopsis: Sets the autoconvert information in the regdb
  532. //
  533. // Effects:
  534. //
  535. // Arguments: [clsidOld] -- the original class id
  536. // [clsidNew] -- that class id that [clsidOld] should be
  537. // auto-converted to
  538. //
  539. // Requires:
  540. //
  541. // Returns: HRESULT
  542. //
  543. // Signals:
  544. //
  545. // Modifies:
  546. //
  547. // Algorithm:
  548. //
  549. // History: dd-mmm-yy Author Comment
  550. // 01-Dec-93 alexgo 32bit port
  551. //
  552. // Notes:
  553. //
  554. //--------------------------------------------------------------------------
  555. #pragma SEG(OleSetAutoConvert)
  556. STDAPI OleSetAutoConvert(REFCLSID clsidOld, REFCLSID clsidNew)
  557. {
  558. OLETRACEIN((API_OleSetAutoConvert, PARAMFMT("clsidOld= %I, clsidNew= %I"),
  559. &clsidOld, &clsidNew));
  560. VDATEHEAP();
  561. HRESULT hresult;
  562. HKEY hkeyClsid = NULL;
  563. ErrRtnH(CoOpenClassKey(clsidOld, TRUE, &hkeyClsid));
  564. if (IsEqualCLSID(clsidNew, CLSID_NULL))
  565. {
  566. // ignore error since there may not be a value at present
  567. (void)RegDeleteKey(hkeyClsid, szAutoConverTo);
  568. }
  569. else
  570. {
  571. OLECHAR szClsid[MAX_STR];
  572. Verify(StringFromCLSID2(clsidNew, szClsid, sizeof(szClsid))
  573. != 0);
  574. if (RegSetValue(hkeyClsid, szAutoConverTo, REG_SZ, szClsid,
  575. _xstrlen(szClsid)) != ERROR_SUCCESS)
  576. {
  577. hresult = ResultFromScode(REGDB_E_WRITEREGDB);
  578. }
  579. }
  580. errRtn:
  581. CLOSE(hkeyClsid);
  582. OLETRACEOUT((API_OleSetAutoConvert, hresult));
  583. return hresult;
  584. }