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.

355 lines
8.7 KiB

  1. /*
  2. * MSVFW32: (Compman, drawdib and video)
  3. *
  4. * profile.c
  5. *
  6. * win32/win16 utility functions to read and write profile items
  7. * for VFW
  8. *
  9. * JMK: added functions to convert from Ansi to Unicode & back
  10. *
  11. * WARNING: This code caches open registry keys. When a profile call
  12. * is made the code looks for an atom to correspond to the appname supplied.
  13. * If an atom is found, then the table of cached registry keys is searched
  14. * for the matching registry handle. If the handle exists, it is used.
  15. * No handle would mean that someone else registered an atom using this
  16. * name, so we proceed to the next step.
  17. *
  18. * No atom found, or no matching registry handle, means that we have to
  19. * open a registry key. If successful, and there is space in the cache,
  20. * we AddAtom the appname, and cache the registry key before returning to
  21. * the caller.
  22. */
  23. #include <windows.h>
  24. #include <windowsx.h>
  25. #ifdef _WIN32
  26. // This whole file is only used for 32 bit code. It is the implementation
  27. // that allows Win GetProfilexxx calls to use the registry.
  28. #include <profile.key>
  29. #include <win32.h>
  30. #include <profile.key>
  31. #include "mmsystem.h"
  32. #include <vfw.h>
  33. #include "msvideoi.h"
  34. #include "debug.h"
  35. #include "profile.h"
  36. #if MMPROFILECACHE
  37. #ifdef DEBUG
  38. #define KEYSCACHED 3 // Normally DrawDib, Debug and ??
  39. #else
  40. #define KEYSCACHED 2 // Normally DrawDib and ??
  41. #endif
  42. HKEY ahkey[KEYSCACHED];
  43. ATOM akeyatoms[KEYSCACHED];
  44. UINT keyscached = 0;
  45. #else
  46. #define KEYSCACHED 0
  47. #endif
  48. static HKEY GetKeyA(LPCSTR appname, BOOL * closekey, BOOL fCreate)
  49. {
  50. HKEY key = 0;
  51. char achName[MAX_PATH];
  52. #if !MMPROFILECACHE
  53. *closekey = TRUE;
  54. #else
  55. UINT n;
  56. ATOM atm;
  57. *closekey = FALSE;
  58. //
  59. // See if we have already used this key
  60. //
  61. atm = FindAtomA(appname);
  62. if (atm != 0) {
  63. // Atom exists... search the table for it.
  64. for (n=0; n<keyscached; ++n) {
  65. if (akeyatoms[n] == atm) {
  66. DPF(2,"Found existing key for %s\n", appname);
  67. return ahkey[n];
  68. }
  69. }
  70. }
  71. DPF(2, "No key found for %s", appname);
  72. #endif
  73. lstrcpyA(achName, KEYNAMEA);
  74. lstrcatA(achName, appname);
  75. if ((!fCreate && RegOpenKeyA(ROOTKEY, achName, &key) == ERROR_SUCCESS)
  76. || (fCreate && RegCreateKeyA(ROOTKEY, achName, &key) == ERROR_SUCCESS)) {
  77. #if MMPROFILECACHE
  78. if ((keyscached < KEYSCACHED)
  79. && (atm = AddAtomA(appname))) {
  80. // Add this key to the cache array
  81. akeyatoms[keyscached] = atm;
  82. ahkey[keyscached] = key;
  83. DPF(1, "Adding key %s to cache array in position %d\n", appname, keyscached);
  84. ++keyscached;
  85. } else {
  86. DPF(2,"Not adding key %s to cache array\n", appname);
  87. *closekey = TRUE;
  88. }
  89. #endif
  90. }
  91. return(key);
  92. }
  93. #ifdef UNICODE
  94. static HKEY GetKeyW(LPCWSTR appname, BOOL * closekey, BOOL fCreate) {
  95. HKEY key = 0;
  96. WCHAR achName[MAX_PATH];
  97. #if !MMPROFILECACHE
  98. *closekey = TRUE;
  99. #else
  100. UINT n;
  101. ATOM atm;
  102. *closekey = FALSE;
  103. //
  104. // See if we have already used this key
  105. //
  106. atm = FindAtomW(appname);
  107. if (atm != 0) {
  108. // Atom exists... search the table for it.
  109. for (n=0; n<keyscached; ++n) {
  110. if (akeyatoms[n] == atm) {
  111. DPF(2,"(W)Found existing key for %ls\n", appname);
  112. return ahkey[n];
  113. }
  114. }
  115. }
  116. DPF(2,"(W)No key found for %ls\n", appname);
  117. #endif
  118. lstrcpyW(achName, KEYNAME );
  119. lstrcatW(achName, appname);
  120. if ((!fCreate && RegOpenKeyW(ROOTKEY, achName, &key) == ERROR_SUCCESS)
  121. || (fCreate && RegCreateKeyW(ROOTKEY, achName, &key) == ERROR_SUCCESS)) {
  122. #if MMPROFILECACHE
  123. if (keyscached < KEYSCACHED
  124. && (atm = AddAtomW(appname))) {
  125. // Add this key to the cache array
  126. akeyatoms[keyscached] = atm;
  127. ahkey[keyscached] = key;
  128. DPF(1,"Adding key %ls to cache array in position %d\n", appname, keyscached);
  129. ++keyscached;
  130. } else {
  131. DPF(2,"Not adding key to cache array\n");
  132. *closekey = TRUE;
  133. }
  134. #endif
  135. }
  136. return(key);
  137. }
  138. #define GetKey GetKeyW
  139. #else
  140. #define GetKey GetKeyA
  141. #endif // UNICODE
  142. /*
  143. * read a UINT from the profile, or return default if
  144. * not found.
  145. */
  146. #ifdef _WIN32
  147. UINT
  148. mmGetProfileIntA(LPCSTR appname, LPCSTR valuename, INT uDefault)
  149. {
  150. DWORD dwType;
  151. INT value = uDefault;
  152. DWORD dwData;
  153. int cbData;
  154. BOOL fCloseKey;
  155. HKEY key = GetKeyA(appname, &fCloseKey, FALSE);
  156. if (key) {
  157. cbData = sizeof(dwData);
  158. if (RegQueryValueExA(
  159. key,
  160. (LPSTR)valuename,
  161. NULL,
  162. &dwType,
  163. (PBYTE) &dwData,
  164. &cbData) == ERROR_SUCCESS) {
  165. if (dwType == REG_DWORD || dwType == REG_BINARY) {
  166. value = (INT)dwData;
  167. #ifdef USESTRINGSALSO
  168. } else if (dwType == REG_SZ) {
  169. value = atoi((LPSTR) &dwData);
  170. #endif
  171. }
  172. }
  173. // close open key open if we did not cache it
  174. if (fCloseKey) {
  175. RegCloseKey(key);
  176. }
  177. }
  178. return((UINT)value);
  179. }
  180. #endif
  181. /*
  182. * read a string from the profile into pResult.
  183. * result is number of bytes written into pResult
  184. */
  185. #ifdef _WIN32
  186. DWORD
  187. mmGetProfileString(
  188. LPCTSTR appname,
  189. LPCTSTR valuename,
  190. LPCTSTR pDefault,
  191. LPTSTR pResult,
  192. int cbResult
  193. )
  194. {
  195. DWORD dwType;
  196. BOOL fCloseKey;
  197. HKEY key = GetKey(appname, &fCloseKey, FALSE);
  198. if (key) {
  199. cbResult = cbResult * sizeof(TCHAR);
  200. if (RegQueryValueEx(
  201. key,
  202. (LPTSTR)valuename,
  203. NULL,
  204. &dwType,
  205. (LPBYTE)pResult,
  206. &cbResult) == ERROR_SUCCESS) {
  207. if (dwType == REG_SZ) {
  208. // cbResult is set to the size including null
  209. // we return the number of characters
  210. // close key if we did not cache it
  211. if (fCloseKey) {
  212. RegCloseKey(key);
  213. }
  214. return(cbResult/sizeof(TCHAR) - 1);
  215. }
  216. }
  217. // close open key if we did not cache it
  218. if (fCloseKey) {
  219. RegCloseKey(key);
  220. }
  221. }
  222. // if we got here, we didn't find it, or it was the wrong type - return
  223. // the default string
  224. lstrcpy(pResult, pDefault);
  225. return(lstrlen(pDefault));
  226. }
  227. #endif
  228. /*
  229. * write a string to the profile
  230. */
  231. #ifdef _WIN32
  232. VOID
  233. mmWriteProfileString(LPCTSTR appname, LPCTSTR valuename, LPCTSTR pData)
  234. {
  235. BOOL fCloseKey;
  236. HKEY key = GetKey(appname, &fCloseKey, TRUE);
  237. if (key) {
  238. if (pData) {
  239. RegSetValueEx(
  240. key,
  241. (LPTSTR)valuename,
  242. 0,
  243. REG_SZ,
  244. (LPBYTE)pData,
  245. (lstrlen(pData) + 1) * sizeof(TCHAR)
  246. );
  247. } else {
  248. RegDeleteValue(
  249. key,
  250. (LPTSTR)valuename
  251. );
  252. }
  253. if (fCloseKey) {
  254. RegCloseKey(key);
  255. }
  256. }
  257. }
  258. /*****************************************************************************
  259. functions to help convert wide characters to multibyte & vv. (using
  260. functions to control code size...)
  261. these functions are not needed if we are building 16 bit code
  262. ****************************************************************************/
  263. /*
  264. * convert an Ansi string to Unicode
  265. */
  266. LPWSTR mmAnsiToWide (
  267. LPWSTR lpwsz, // out: wide char buffer to convert into
  268. LPCSTR lpsz, // in: ansi string to convert from
  269. UINT nChars) // in: count of characters in each buffer
  270. {
  271. MultiByteToWideChar(GetACP(), 0, lpsz, nChars, lpwsz, nChars);
  272. return lpwsz;
  273. }
  274. /*
  275. * convert a unicode string to ansi
  276. */
  277. LPSTR mmWideToAnsi (
  278. LPSTR lpsz, // out: ansi buffer to convert into
  279. LPCWSTR lpwsz, // in: wide char buffer to convert from
  280. UINT nChars) // in: count of characters (not bytes!)
  281. {
  282. WideCharToMultiByte(GetACP(), 0, lpwsz, nChars, lpsz, nChars, NULL, NULL);
  283. return lpsz;
  284. }
  285. /*
  286. * Close all open registry keys
  287. */
  288. #if MMPROFILECACHE
  289. VOID CloseKeys()
  290. {
  291. for (; keyscached--;) {
  292. #ifdef DEBUG
  293. if (!ahkey[keyscached]) { //Assertion!
  294. DPF(0,"Closing a null key\n");
  295. //DebugBreak();
  296. }
  297. #endif
  298. RegCloseKey(ahkey[keyscached]);
  299. DeleteAtom(akeyatoms[keyscached]);
  300. }
  301. }
  302. #endif //MMPROFILECACHE
  303. #endif // _WIN32
  304. #endif