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.

503 lines
9.9 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. mapembed.c
  5. Abstract:
  6. This module contains the functions that perform the mapping
  7. between the "embedding" section of win.ini, and the subkeys
  8. of HKEY_CLASSES_ROOT.
  9. This mapping is a hack implemented on Win3.1, that must also
  10. exist on NT.
  11. It is implemnted in the WOW layer, since only some win16 apps
  12. that read or write to the "embedding" section ( WinWord and
  13. MsMail) depend on it.
  14. Author:
  15. Jaime F. Sasson (jaimes) 25-Nov-1992
  16. --*/
  17. #include "precomp.h"
  18. #pragma hdrstop
  19. MODNAME(mapembed.c);
  20. #define WININITIMEOUT 2000
  21. #define BUFFER_SIZE 128
  22. #define EMPTY_STRING ""
  23. DWORD _LastTimeUpdated = 0;
  24. BOOL
  25. IsWinIniHelper(
  26. IN LPSTR FileName
  27. )
  28. /*++
  29. Routine Description:
  30. Determine if the name passed as argument refers to the file win.ini.
  31. Used by IS_WIN_INI macro, which assures the argument is non-null and
  32. deals with exact match of "win.ini".
  33. Arguments:
  34. FileName - File name to be examined.
  35. Return Value:
  36. BOOL - Returns TRUE if 'Name' refers to win.ini.
  37. Otherwise, returns FALSE.
  38. --*/
  39. {
  40. CHAR BufferForFullPath[MAX_PATH];
  41. PSTR PointerToName;
  42. DWORD SizeOfFullPath;
  43. BOOL Result;
  44. #ifdef DEBUG
  45. //
  46. // Filename argument must already be lowercase. Be sure.
  47. //
  48. {
  49. char Lowercase[MAX_PATH];
  50. WOW32ASSERT(strlen(FileName) < MAX_PATH-1);
  51. strcpy(Lowercase, FileName);
  52. WOW32_strlwr(Lowercase);
  53. WOW32ASSERT(!WOW32_strcmp(FileName, Lowercase));
  54. }
  55. #endif
  56. if (!WOW32_strcmp(FileName, szWinDotIni)) {
  57. Result = TRUE;
  58. goto Done;
  59. }
  60. SizeOfFullPath = GetFullPathName( FileName,
  61. sizeof BufferForFullPath,
  62. BufferForFullPath,
  63. &PointerToName );
  64. if (SizeOfFullPath == 0) {
  65. Result = FALSE;
  66. goto Done;
  67. }
  68. WOW32ASSERT( (SizeOfFullPath + 1) <= sizeof BufferForFullPath );
  69. WOW32ASSERTMSG(pszWinIniFullPath && pszWinIniFullPath[0],
  70. "WOW32 ERROR pszWinIniFullPath not initialized.\n");
  71. Result = !WOW32_stricmp( pszWinIniFullPath, BufferForFullPath );
  72. Done:
  73. return Result;
  74. }
  75. VOID
  76. UpdateEmbeddingAllKeys(
  77. )
  78. /*++
  79. Routine Description:
  80. Update the "embedding" section of win.ini based on the information
  81. stored on the subkeys of HKEY_CLASSES_ROOT.
  82. Arguments:
  83. None.
  84. Return Value:
  85. None.
  86. --*/
  87. {
  88. LONG iClass;
  89. CHAR szClass[MAX_PATH + 1];
  90. LONG Status;
  91. for (iClass = 0;
  92. (Status = RegEnumKey(HKEY_CLASSES_ROOT,iClass,szClass,sizeof( szClass ))) != ERROR_NO_MORE_ITEMS;
  93. iClass++)
  94. {
  95. if( Status == ERROR_SUCCESS ) {
  96. UpdateEmbeddingKey( szClass );
  97. }
  98. }
  99. }
  100. VOID
  101. UpdateEmbeddingKey(
  102. IN LPSTR KeyName
  103. )
  104. /*++
  105. Routine Description:
  106. Update one key of the "embedding" section of win.ini based on the
  107. information stored on the correspondent subkey of HKEY_CLASSES_ROOT.
  108. The code below is an improved version of the function
  109. "UpdateWinIni" extracted from Win 3.1 (shell\library\dbf.c).
  110. Arguments:
  111. KeyName - Name of the key to be updated.
  112. Return Value:
  113. None.
  114. --*/
  115. {
  116. LONG Status;
  117. HKEY Key;
  118. PSTR szClass;
  119. LPSTR szClassName;
  120. CHAR BufferForClassName[BUFFER_SIZE];
  121. // char szClassName[60];
  122. LPSTR szServer;
  123. CHAR BufferForServer[BUFFER_SIZE];
  124. // char szServer[64];
  125. LPSTR szLine;
  126. CHAR BufferForLine[2*BUFFER_SIZE];
  127. // char szLine[128];
  128. char szOldLine[2*BUFFER_SIZE];
  129. // char szOldLine[128];
  130. LPSTR lpDesc, lpForms;
  131. int nCommas;
  132. LONG cchClassNameSize;
  133. LONG cchServerSize;
  134. LONG cchLineSize;
  135. if( KeyName == NULL ) {
  136. return;
  137. }
  138. szClass = KeyName;
  139. Key = NULL;
  140. szClassName = BufferForClassName;
  141. cchClassNameSize = sizeof( BufferForClassName );
  142. szServer = BufferForServer;
  143. cchServerSize = sizeof( BufferForServer );
  144. szLine = BufferForLine;
  145. if( RegOpenKey( HKEY_CLASSES_ROOT, szClass, &Key ) != ERROR_SUCCESS )
  146. goto NukeClass;
  147. Status = RegQueryValue(Key,NULL,szClassName,&cchClassNameSize);
  148. if( ( Status != ERROR_SUCCESS ) &&
  149. ( Status != ERROR_MORE_DATA ) )
  150. goto NukeClass;
  151. if( Status == ERROR_MORE_DATA ) {
  152. cchClassNameSize++;
  153. szClassName = ( PSTR )malloc_w( cchClassNameSize );
  154. if( szClassName == NULL )
  155. goto NukeClass;
  156. Status = RegQueryValue(Key,NULL,szClassName,&cchClassNameSize);
  157. if( Status != ERROR_SUCCESS )
  158. goto NukeClass;
  159. }
  160. if (!*szClassName)
  161. goto NukeClass;
  162. Status = RegQueryValue(Key,szServerKey,szServer,&cchServerSize);
  163. if( ( Status != ERROR_SUCCESS ) &&
  164. ( Status != ERROR_MORE_DATA ) )
  165. goto NukeClass;
  166. if( Status == ERROR_MORE_DATA ) {
  167. cchServerSize++;
  168. szServer = malloc_w( cchServerSize );
  169. if( szServer == NULL )
  170. goto NukeClass;
  171. Status = RegQueryValue(Key,szServerKey,szServer,&cchServerSize);
  172. if( Status != ERROR_SUCCESS )
  173. goto NukeClass;
  174. }
  175. if (!*szServer)
  176. goto NukeClass;
  177. if (GetProfileString(szEmbedding, szClass, EMPTY_STRING,
  178. szOldLine, sizeof(szOldLine)))
  179. {
  180. for (lpForms=szOldLine, nCommas=0; ; lpForms=AnsiNext(lpForms))
  181. {
  182. while (*lpForms == ',')
  183. {
  184. *lpForms++ = '\0';
  185. if (++nCommas == 3)
  186. goto FoundForms;
  187. }
  188. if (!*lpForms)
  189. goto DoDefaults;
  190. }
  191. FoundForms:
  192. lpDesc = szOldLine;
  193. }
  194. else
  195. {
  196. DoDefaults:
  197. lpDesc = szClassName;
  198. lpForms = szPicture;
  199. }
  200. // we have a class, a classname, and a server, so its an le class
  201. cchLineSize = strlen( lpDesc ) +
  202. strlen( szClassName ) +
  203. strlen( szServer ) +
  204. strlen( lpForms ) +
  205. 3 +
  206. 1;
  207. if( cchLineSize > sizeof( BufferForLine ) ) {
  208. szLine = malloc_w( cchLineSize );
  209. if( szLine == NULL )
  210. goto NukeClass;
  211. }
  212. wsprintf(szLine, "%s,%s,%s,%s",
  213. lpDesc, (LPSTR)szClassName, (LPSTR)szServer, lpForms);
  214. WriteProfileString(szEmbedding, szClass, szLine);
  215. if( Key != NULL ) {
  216. RegCloseKey( Key );
  217. }
  218. if( szClassName != BufferForClassName ) {
  219. free_w( szClassName );
  220. }
  221. if( szServer != BufferForServer ) {
  222. free_w( szServer );
  223. }
  224. if( szLine != BufferForLine ) {
  225. free_w( szLine );
  226. }
  227. return;
  228. NukeClass:
  229. /*
  230. Don't nuke the class because someone else may use it!
  231. */
  232. if( Key != NULL ) {
  233. RegCloseKey( Key );
  234. }
  235. if( szClassName != BufferForClassName ) {
  236. free_w( szClassName );
  237. }
  238. if( szServer != BufferForServer ) {
  239. free_w( szServer );
  240. }
  241. if( szLine != BufferForLine ) {
  242. free_w( szLine );
  243. }
  244. WriteProfileString(szEmbedding,szClass,NULL);
  245. }
  246. VOID
  247. UpdateClassesRootSubKey(
  248. IN LPSTR KeyName,
  249. IN LPSTR Value
  250. )
  251. /*++
  252. Routine Description:
  253. Update a subkeys of HKEY_CLASSES_ROOT, based on the corresponding
  254. key in the "embedding" section of win.ini.
  255. The code below is an improved version of the function
  256. "UpdateFromWinIni" extracted from Win 3.1 (shell\library\dbf.c).
  257. Arguments:
  258. KeyName - Name of the subkey to be updated
  259. Value - The value associated to the key, that was already written
  260. to the "embedding" section of win.ini.
  261. Return Value:
  262. None.
  263. --*/
  264. {
  265. LPSTR szLine;
  266. LPSTR lpClass,lpServer,lpClassName;
  267. LPSTR lpT;
  268. HKEY key = NULL;
  269. HKEY key1 = NULL;
  270. if( ( KeyName == NULL ) || ( Value == NULL ) ) {
  271. return;
  272. }
  273. lpClass = KeyName;
  274. szLine = Value;
  275. if (!(lpClassName=WOW32_strchr(szLine, ',')))
  276. return;
  277. // get the server name and null terminate the class name
  278. if (!(lpServer=WOW32_strchr(++lpClassName, ','))) {
  279. return;
  280. }
  281. *lpServer++ = '\0';
  282. // null terminate the server
  283. if (!(lpT=WOW32_strchr(lpServer, ','))) {
  284. return;
  285. }
  286. *lpT++ = '\0';
  287. // make sure the classname is nonblank
  288. while (*lpClassName == ' ')
  289. lpClassName++;
  290. if (!*lpClassName)
  291. return;
  292. // make sure the server name is nonblank
  293. while (*lpServer == ' ')
  294. lpServer++;
  295. if (!*lpServer)
  296. return;
  297. // we now have a valid entry
  298. key = NULL;
  299. if( ( RegCreateKey( HKEY_CLASSES_ROOT, lpClass, &key ) != ERROR_SUCCESS ) ||
  300. ( RegSetValue( key, NULL, REG_SZ, lpClassName, strlen( lpClassName ) ) != ERROR_SUCCESS ) ) {
  301. if( key != NULL ) {
  302. RegCloseKey( key );
  303. }
  304. return;
  305. }
  306. if( ( RegCreateKey( key, szServerKey, &key1 ) != ERROR_SUCCESS ) ||
  307. ( RegSetValue( key1, NULL, REG_SZ, lpServer, strlen( lpServer ) ) != ERROR_SUCCESS ) ) {
  308. if( key != NULL ) {
  309. RegCloseKey( key );
  310. }
  311. if( key1 != NULL ) {
  312. RegCloseKey( key1 );
  313. }
  314. return;
  315. }
  316. RegCloseKey( key );
  317. RegCloseKey( key1 );
  318. }
  319. VOID
  320. SetLastTimeUpdated(
  321. )
  322. /*++
  323. Routine Description:
  324. Set the variable that contains the information of when the "embedding"
  325. section of win.ini was last updated.
  326. Arguments:
  327. None.
  328. Return Value:
  329. None.
  330. --*/
  331. {
  332. _LastTimeUpdated = GetTickCount();
  333. }
  334. BOOL
  335. WasSectionRecentlyUpdated(
  336. )
  337. /*++
  338. Routine Description:
  339. Inform the caller whether the "embedding" section of win.ini
  340. was recently updated ( less than 2 seconds ).
  341. Arguments:
  342. None.
  343. Return Value:
  344. BOOLEAN - Returns TRUE if the "embedding" section was updated less than
  345. 2 seconds ago.
  346. --*/
  347. {
  348. DWORD Now;
  349. Now = GetTickCount();
  350. return( ( ( Now - _LastTimeUpdated ) < WININITIMEOUT ) ? TRUE : FALSE );
  351. }