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.

808 lines
18 KiB

  1. /***************************************************************************
  2. Name : REGISTRY.C
  3. Comment : INIfile handling
  4. Revision Log
  5. Date Name Description
  6. -------- ----- ---------------------------------------------------------
  7. ***************************************************************************/
  8. #include "prep.h"
  9. #include "efaxcb.h"
  10. #include "t30.h"
  11. #include "hdlc.h"
  12. #include "debug.h"
  13. #include "glbproto.h"
  14. #ifdef USE_REGISTRY
  15. // The default database to us
  16. # define DATABASE_KEY HKEY_LOCAL_MACHINE
  17. // These are NOT localizable items.
  18. # define szKEYPREFIX "SOFTWARE\\Microsoft\\Fax\\Devices"
  19. # define szKEYCLASS "DATA"
  20. DWORD my_atoul(LPSTR lpsz);
  21. #else // !USE_REGISTRY
  22. BOOL expand_key(DWORD dwKey, LPSTR FAR *lplpszKey,
  23. LPSTR FAR *lplpszProfileName);
  24. #endif // !USE_REGISTRY
  25. ULONG_PTR ProfileOpen(DWORD dwProfileID, LPSTR lpszSection, DWORD dwFlags)
  26. {
  27. ULONG_PTR dwRet = 0;
  28. #ifdef USE_REGISTRY
  29. char rgchKey[128];
  30. HKEY hKey=0;
  31. HKEY hBaseKey = DATABASE_KEY;
  32. LONG l;
  33. LPSTR lpszPrefix;
  34. DWORD sam=0;
  35. BG_CHK(sizeof(hKey)<=sizeof(ULONG_PTR));
  36. if (dwProfileID==OEM_BASEKEY)
  37. {
  38. hBaseKey = HKEY_LOCAL_MACHINE;
  39. lpszPrefix= ""; // we don't prepend szKEYPREFIX
  40. if (!lpszSection) goto failure;
  41. }
  42. else if (lpszSection)
  43. {
  44. lpszPrefix= szKEYPREFIX "\\";
  45. }
  46. else
  47. {
  48. lpszPrefix= szKEYPREFIX;
  49. lpszSection="";
  50. }
  51. if ((lstrlen(lpszPrefix)+lstrlen(lpszSection))>=sizeof(rgchKey))
  52. goto failure;
  53. lstrcpy(rgchKey, lpszPrefix);
  54. lstrcat(rgchKey, lpszSection);
  55. sam = 0;
  56. if (dwFlags &fREG_READ) sam |= KEY_READ;
  57. if (dwFlags &fREG_WRITE) sam |= KEY_WRITE;
  58. if (dwFlags & fREG_CREATE)
  59. {
  60. DWORD dwDisposition=0;
  61. DWORD dwOptions = (dwFlags & fREG_VOLATILE)
  62. ?REG_OPTION_VOLATILE
  63. :REG_OPTION_NON_VOLATILE;
  64. sam = KEY_READ | KEY_WRITE; // we force sam to this when creating.
  65. l = RegCreateKeyEx(
  66. hBaseKey, // handle of open key
  67. rgchKey, // address of name of subkey to open
  68. 0, // reserved
  69. szKEYCLASS, // address of class string
  70. dwOptions, // special options flag
  71. sam, // desired security access
  72. NULL, // address of key security structure
  73. &hKey, // address of buffer for opened handle
  74. &dwDisposition // address of dispostion value buffer
  75. );
  76. }
  77. else
  78. {
  79. l = RegOpenKeyEx(
  80. hBaseKey, // handle of open key
  81. rgchKey, // address of name of subkey to open
  82. 0, // reserved
  83. sam , // desired security access
  84. &hKey // address of buffer for opened handle
  85. );
  86. }
  87. if (l!=ERROR_SUCCESS)
  88. {
  89. //LOG((_ERR, "RegCreateKeyEx returns error %ld\n", (long) l));
  90. goto failure;
  91. }
  92. dwRet = (ULONG_PTR) hKey;
  93. #else // !USE_REGISTRY
  94. LPSTR lpszFile= szINIFILE;
  95. ATOM aSection, aProfile;
  96. // NULL lpszSection not supported.
  97. if (!lpszSection) goto failure;
  98. if (!(aSection = GlobalAddAtom(lpszSection)))
  99. goto failure;
  100. if (!(aProfile = GlobalAddAtom(lpszFile)))
  101. {GlobalDeleteAtom(aSection); goto failure;}
  102. dwRet = MAKELONG(aSection, aProfile);
  103. #endif // !USE_REGISTRY
  104. BG_CHK(dwRet);
  105. return dwRet;
  106. failure:
  107. return 0;
  108. }
  109. UINT
  110. ProfileListGetInt(
  111. ULONG_PTR KeyList[10],
  112. LPSTR lpszValueName,
  113. UINT uDefault
  114. )
  115. {
  116. int i;
  117. int Num=0;
  118. UINT uRet = uDefault;
  119. BOOL fExist = 0;
  120. for (i=0; i<10; i++) {
  121. if (KeyList[i] == 0) {
  122. Num = i-1;
  123. break;
  124. }
  125. }
  126. for (i=Num; i>=0; i--) {
  127. uRet = ProfileGetInt (KeyList[i], lpszValueName, uDefault, &fExist);
  128. if (fExist) {
  129. return uRet;
  130. }
  131. }
  132. return uRet;
  133. }
  134. UINT ProfileGetInt(ULONG_PTR dwKey, LPSTR lpszValueName, UINT uDefault, BOOL *fExist)
  135. {
  136. UINT uRet = uDefault;
  137. char rgchBuf[128];
  138. DWORD dwType;
  139. DWORD dwcbSize=sizeof(rgchBuf);
  140. LONG l = RegQueryValueEx(
  141. (HKEY) dwKey,
  142. lpszValueName,
  143. 0,
  144. &dwType,
  145. rgchBuf,
  146. &dwcbSize
  147. );
  148. if (fExist) {
  149. *fExist = 0;
  150. }
  151. if (l!=ERROR_SUCCESS)
  152. {
  153. //LOG((_ERR, "RegQueryValueEx returned error %ld\n", (long) l));
  154. goto end;
  155. }
  156. if (fExist) {
  157. *fExist = 1;
  158. }
  159. if (dwType != REG_SZ)
  160. {
  161. //LOG((_ERR, "RegQueryValueEx value type not string:0x%lx\n",
  162. // (unsigned long) dwType));
  163. goto end;
  164. }
  165. uRet = (UINT) my_atoul(rgchBuf);
  166. end:
  167. return uRet;
  168. }
  169. DWORD ProfileGetString(ULONG_PTR dwKey, LPSTR lpszValueName,
  170. LPSTR lpszDefault, LPSTR lpszBuf , DWORD dwcbMax)
  171. {
  172. DWORD dwRet = 0;
  173. #ifdef USE_REGISTRY
  174. DWORD dwType;
  175. LONG l = RegQueryValueEx(
  176. (HKEY) dwKey,
  177. lpszValueName,
  178. 0,
  179. &dwType,
  180. lpszBuf,
  181. &dwcbMax
  182. );
  183. if (l!=ERROR_SUCCESS)
  184. {
  185. //LOG((_ERR, "RegQueryValueEx returned error %ld\n", (long) l));
  186. goto copy_default;
  187. }
  188. if (dwType != REG_SZ)
  189. {
  190. //LOG((_ERR, "RegQueryValueEx value type not string:0x%lx\n",
  191. // (unsigned long) dwType));
  192. goto copy_default;
  193. }
  194. // Make sure we null-terminate the string and return the true string
  195. // length..
  196. if (dwcbMax) {lpszBuf[dwcbMax-1]=0; dwcbMax = (DWORD) lstrlen(lpszBuf);}
  197. dwRet = dwcbMax;
  198. goto end;
  199. #else // USE_REGISTRY
  200. LPSTR lpszKey;
  201. LPSTR lpszProfileName;
  202. if (!expand_key(dwKey, &lpszKey, &lpszProfileName)) goto copy_default;
  203. dwRet = GetPrivateProfileString(lpszKey, lpszValueName,
  204. lpszDefault, lpszBuf , (INT) dwcbMax,
  205. lpszProfileName);
  206. goto end;
  207. #endif // USE_REGISTRY
  208. BG_CHK(FALSE);
  209. copy_default:
  210. dwRet = 0;
  211. if (!lpszDefault || !*lpszDefault)
  212. {
  213. if (dwcbMax) *lpszBuf=0;
  214. }
  215. else
  216. {
  217. UINT cb = _fstrlen(lpszDefault)+1;
  218. if (cb>(UINT)dwcbMax) cb=dwcbMax;
  219. if (cb)
  220. {
  221. _fmemcpy(lpszBuf, lpszDefault, cb);
  222. lpszBuf[cb-1]=0;
  223. dwRet = cb-1;
  224. }
  225. }
  226. // fall through...
  227. end:
  228. return dwRet;
  229. }
  230. BOOL
  231. ProfileWriteString(
  232. ULONG_PTR dwKey,
  233. LPSTR lpszValueName,
  234. LPSTR lpszBuf,
  235. BOOL fRemoveCR
  236. )
  237. {
  238. // NOTE: If lpszValueName is null, delete the key. (can't do this in,
  239. // the registry, unfortunately).
  240. // If lpszBuf is null pointer -- "delete" this value.
  241. BOOL fRet=FALSE;
  242. #ifdef USE_REGISTRY
  243. LONG l;
  244. if (!lpszValueName) goto end;
  245. if (!lpszBuf)
  246. {
  247. // delete value...
  248. l = RegDeleteValue((HKEY) dwKey, lpszValueName);
  249. if (l!=ERROR_SUCCESS) goto end;
  250. }
  251. else
  252. {
  253. if (fRemoveCR) {
  254. RemoveCR (lpszBuf);
  255. }
  256. l = RegSetValueEx((HKEY) dwKey, lpszValueName, 0, REG_SZ,
  257. lpszBuf, lstrlen(lpszBuf)+1);
  258. if (l!=ERROR_SUCCESS)
  259. {
  260. //LOG((_ERR,
  261. // "RegSetValueEx(\"%s\", \"%s\") returned error %ld\n",
  262. // (LPSTR) lpszValueName,
  263. // (LPSTR) lpszBuf,
  264. // (long) l));
  265. goto end;
  266. }
  267. }
  268. fRet = TRUE;
  269. goto end;
  270. #else // !USE_REGISTRY
  271. LPSTR lpszKey;
  272. LPSTR lpszProfileName;
  273. if (!expand_key(dwKey, &lpszKey, &lpszProfileName)) goto end;
  274. fRet = WritePrivateProfileString(lpszKey, lpszValueName,
  275. lpszBuf, lpszProfileName);
  276. goto end;
  277. #endif // !USE_REGISTRY
  278. BG_CHK(FALSE);
  279. end:
  280. return fRet;
  281. }
  282. void ProfileClose(ULONG_PTR dwKey)
  283. {
  284. #ifdef USE_REGISTRY
  285. if (RegCloseKey((HKEY)dwKey)!=ERROR_SUCCESS)
  286. {
  287. //LOG((_WRN, "Couldn't close registry key:%lu\n\r",
  288. // (unsigned long) dwKey));
  289. }
  290. #else
  291. BG_CHK(LOWORD(dwKey)); GlobalDeleteAtom(LOWORD(dwKey));
  292. BG_CHK(HIWORD(dwKey)); GlobalDeleteAtom(HIWORD(dwKey));
  293. #endif
  294. }
  295. BOOL ProfileDeleteSection(DWORD dwProfileID, LPSTR lpszSection)
  296. {
  297. #ifdef USE_REGISTRY
  298. char rgchKey[128];
  299. LPSTR lpszPrefix= szKEYPREFIX "\\";
  300. if (dwProfileID==OEM_BASEKEY) goto failure; // Can't delete this
  301. if ((lstrlen(lpszPrefix)+lstrlen(lpszSection))>=sizeof(rgchKey))
  302. goto failure;
  303. lstrcpy(rgchKey, lpszPrefix);
  304. lstrcat(rgchKey, lpszSection);
  305. return (RegDeleteKey(DATABASE_KEY, rgchKey)==ERROR_SUCCESS);
  306. failure:
  307. return FALSE;
  308. #else // !USE_REGISTRY
  309. return WritePrivateProfileString(lpszSection, NULL, NULL, szINIFILE);
  310. #endif // !USE_REGISTRY
  311. }
  312. BOOL
  313. ProfileCopyTree(
  314. DWORD dwProfileIDTo,
  315. LPSTR lpszSectionTo,
  316. DWORD dwProfileIDFr,
  317. LPSTR lpszSectionFr)
  318. {
  319. BOOL fRet=TRUE;
  320. char SecTo[200];
  321. char SecFr[200];
  322. //
  323. // Since there is no CopyKeyWithAllSubkeys API, it is difficult to write generic tree-walking algorithm.
  324. // We will hard-code the keys here.
  325. //
  326. // copy Fax key always
  327. ProfileCopySection(dwProfileIDTo,
  328. lpszSectionTo,
  329. dwProfileIDFr,
  330. lpszSectionFr,
  331. TRUE);
  332. // copy Fax/Class1 key if exists
  333. sprintf(SecTo, "%s\\Class1", lpszSectionTo);
  334. sprintf(SecFr, "%s\\Class1", lpszSectionFr);
  335. ProfileCopySection(dwProfileIDTo,
  336. SecTo,
  337. dwProfileIDFr,
  338. SecFr,
  339. FALSE);
  340. // copy Fax/Class1/AdaptiveAnswer key if exists
  341. sprintf(SecTo, "%s\\Class1\\AdaptiveAnswer", lpszSectionTo);
  342. sprintf(SecFr, "%s\\Class1\\AdaptiveAnswer", lpszSectionFr);
  343. ProfileCopySection(dwProfileIDTo,
  344. SecTo,
  345. dwProfileIDFr,
  346. SecFr,
  347. FALSE);
  348. // copy Fax/Class1/AdaptiveAnswer/Answer key if exists
  349. sprintf(SecTo, "%s\\Class1\\AdaptiveAnswer\\AnswerCommand", lpszSectionTo);
  350. sprintf(SecFr, "%s\\Class1\\AdaptiveAnswer\\AnswerCommand", lpszSectionFr);
  351. ProfileCopySection(dwProfileIDTo,
  352. SecTo,
  353. dwProfileIDFr,
  354. SecFr,
  355. FALSE);
  356. // copy Fax/Class2 key if exists
  357. sprintf(SecTo, "%s\\Class2", lpszSectionTo);
  358. sprintf(SecFr, "%s\\Class2", lpszSectionFr);
  359. ProfileCopySection(dwProfileIDTo,
  360. SecTo,
  361. dwProfileIDFr,
  362. SecFr,
  363. FALSE);
  364. // copy Fax/Class2/AdaptiveAnswer key if exists
  365. sprintf(SecTo, "%s\\Class2\\AdaptiveAnswer", lpszSectionTo);
  366. sprintf(SecFr, "%s\\Class2\\AdaptiveAnswer", lpszSectionFr);
  367. ProfileCopySection(dwProfileIDTo,
  368. SecTo,
  369. dwProfileIDFr,
  370. SecFr,
  371. FALSE);
  372. // copy Fax/Class2/AdaptiveAnswer/Answer key if exists
  373. sprintf(SecTo, "%s\\Class2\\AdaptiveAnswer\\AnswerCommand", lpszSectionTo);
  374. sprintf(SecFr, "%s\\Class2\\AdaptiveAnswer\\AnswerCommand", lpszSectionFr);
  375. ProfileCopySection(dwProfileIDTo,
  376. SecTo,
  377. dwProfileIDFr,
  378. SecFr,
  379. FALSE);
  380. // copy Fax/Class2_0 key if exists
  381. sprintf(SecTo, "%s\\Class2_0", lpszSectionTo);
  382. sprintf(SecFr, "%s\\Class2_0", lpszSectionFr);
  383. ProfileCopySection(dwProfileIDTo,
  384. SecTo,
  385. dwProfileIDFr,
  386. SecFr,
  387. FALSE);
  388. // copy Fax/Class2_0/AdaptiveAnswer key if exists
  389. sprintf(SecTo, "%s\\Class2_0\\AdaptiveAnswer", lpszSectionTo);
  390. sprintf(SecFr, "%s\\Class2_0\\AdaptiveAnswer", lpszSectionFr);
  391. ProfileCopySection(dwProfileIDTo,
  392. SecTo,
  393. dwProfileIDFr,
  394. SecFr,
  395. FALSE);
  396. // copy Fax/Class2/AdaptiveAnswer/Answer key if exists
  397. sprintf(SecTo, "%s\\Class2_0\\AdaptiveAnswer\\AnswerCommand", lpszSectionTo);
  398. sprintf(SecFr, "%s\\Class2_0\\AdaptiveAnswer\\AnswerCommand", lpszSectionFr);
  399. ProfileCopySection(dwProfileIDTo,
  400. SecTo,
  401. dwProfileIDFr,
  402. SecFr,
  403. FALSE);
  404. return fRet;
  405. }
  406. BOOL
  407. ProfileCopySection(
  408. DWORD dwProfileIDTo,
  409. LPSTR lpszSectionTo,
  410. DWORD dwProfileIDFr,
  411. LPSTR lpszSectionFr,
  412. BOOL fCreateAlways
  413. )
  414. {
  415. BOOL fRet=FALSE;
  416. DWORD iValue=0;
  417. DWORD cbValue, cbData, dwType;
  418. char rgchValue[60], rgchData[256];
  419. HKEY hkFr;
  420. HKEY hkTo;
  421. hkFr = (HKEY) ProfileOpen(dwProfileIDFr, lpszSectionFr, fREG_READ);
  422. if ( (!hkFr) && (!fCreateAlways) ) {
  423. return fRet;
  424. }
  425. hkTo = (HKEY) ProfileOpen(dwProfileIDTo, lpszSectionTo,
  426. fREG_CREATE |fREG_READ|fREG_WRITE);
  427. if (!hkTo || !hkFr) goto end;
  428. iValue=0;dwType=0;cbValue=sizeof(rgchValue);cbData=sizeof(rgchData);
  429. while(RegEnumValue(hkFr, iValue, rgchValue, &cbValue,
  430. NULL, &dwType, rgchData, &cbData)==ERROR_SUCCESS)
  431. {
  432. if (RegQueryValueEx(hkFr, rgchValue, NULL, &dwType, rgchData, &cbData)
  433. ==ERROR_SUCCESS)
  434. {
  435. if (RegSetValueEx(hkTo, rgchValue, 0, dwType, rgchData, cbData)
  436. == ERROR_SUCCESS)
  437. {
  438. fRet=TRUE;
  439. }
  440. }
  441. iValue++;dwType=0;cbValue=sizeof(rgchValue);cbData=sizeof(rgchData);
  442. }
  443. end:
  444. if (hkTo) RegCloseKey(hkTo);
  445. if (hkFr) RegCloseKey(hkFr);
  446. return fRet;
  447. }
  448. DWORD ProfileGetData(ULONG_PTR dwKey, LPSTR lpszValueName,
  449. LPBYTE lpbBuf , DWORD dwcbMax)
  450. {
  451. #ifndef USE_REGISTRY
  452. return 0;
  453. #else // USE_REGISTRY
  454. DWORD dwType;
  455. LONG l = RegQueryValueEx(
  456. (HKEY) dwKey,
  457. lpszValueName,
  458. 0,
  459. &dwType,
  460. lpbBuf,
  461. &dwcbMax
  462. );
  463. if (l!=ERROR_SUCCESS)
  464. {
  465. //LOG((_ERR, "RegQueryValueEx returned error %ld\n", (long) l));
  466. goto copy_default;
  467. }
  468. if (dwType != REG_BINARY)
  469. {
  470. goto copy_default;
  471. }
  472. return dwcbMax;
  473. copy_default:
  474. return 0;
  475. #endif // USE_REGISTRY
  476. }
  477. BOOL ProfileWriteData(ULONG_PTR dwKey, LPSTR lpszValueName,
  478. LPBYTE lpbBuf, DWORD dwcb)
  479. {
  480. #ifndef USE_REGISTRY
  481. return 0;
  482. #else // USE_REGISTRY
  483. LONG l = ~(ERROR_SUCCESS);
  484. if (!lpszValueName) goto end;
  485. if (!lpbBuf)
  486. {
  487. // delete value...
  488. l = RegDeleteValue((HKEY) dwKey, lpszValueName);
  489. }
  490. else
  491. {
  492. l = RegSetValueEx((HKEY) dwKey, lpszValueName, 0, REG_BINARY,
  493. lpbBuf, dwcb);
  494. }
  495. end:
  496. return (l==ERROR_SUCCESS);
  497. #endif // USE_REGISTRY
  498. }
  499. #ifdef USE_REGISTRY
  500. DWORD my_atoul(LPSTR lpsz)
  501. {
  502. unsigned i=8, c;
  503. unsigned long ul=0;
  504. while(i-- && (c=*lpsz++)) {
  505. ul*=10;
  506. switch(c) {
  507. case '0': break;
  508. case '1':ul+=1; break;
  509. case '2':ul+=2; break;
  510. case '3':ul+=3; break;
  511. case '4':ul+=4; break;
  512. case '5':ul+=5; break;
  513. case '6':ul+=6; break;
  514. case '7':ul+=7; break;
  515. case '8':ul+=8; break;
  516. case '9':ul+=9; break;
  517. default: goto end;
  518. }
  519. }
  520. end:
  521. return ul;
  522. }
  523. #endif // USE_REGISTRY