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.

199 lines
7.2 KiB

  1. /*----------------------------------------------------------------------------
  2. / Title;
  3. / cabstate.c => cabinet state i/o
  4. /
  5. / Purpose:
  6. / Provides a clean API to fill out the cabinet state from the registry, if the
  7. / relevent keys cannot be found then we set the relevant defaults. This is
  8. / called by the explorer.
  9. /
  10. / History:
  11. / 23apr96 daviddv New API which passes the structure size in
  12. / 18mar96 daviddv Bug fix; Added colour state to FALSE when state structure not read
  13. / 7feb96 daviddv Tweeked cabinet state writing
  14. / 30jan96 daviddv Created
  15. /
  16. /----------------------------------------------------------------------------*/
  17. #include "shellprv.h"
  18. #include "regstr.h"
  19. #include "cstrings.h"
  20. #pragma hdrstop
  21. TCHAR const c_szCabinetState[] = REGSTR_PATH_EXPLORER TEXT( "\\CabinetState");
  22. TCHAR const c_szSettings[] = TEXT("Settings");
  23. TCHAR const c_szFullPath[] = TEXT("FullPath");
  24. /*----------------------------------------------------------------------------
  25. / Read in the CABINETSTATE structure from the registry and attempt to validate it.
  26. /
  27. / Notes:
  28. / -
  29. /
  30. / In:
  31. / lpCabinetState => pointer to CABINETSTATE structure to be filled.
  32. / cLength = size of structure to be filled
  33. /
  34. / Out:
  35. / [lpState] filled in with data
  36. / fReadFromRegistry == indicates if the structure was actually read from the registry
  37. / or if we are giviing the client a default one.
  38. /----------------------------------------------------------------------------*/
  39. STDAPI_(BOOL) ReadCabinetState( CABINETSTATE *lpState, int cLength )
  40. {
  41. DWORD cbData = SIZEOF(CABINETSTATE);
  42. BOOL fReadFromRegistry = FALSE;
  43. CABINETSTATE state;
  44. SHELLSTATE ss;
  45. DWORD dwType;
  46. HKEY hKey;
  47. ASSERT( lpState );
  48. SHGetSetSettings(&ss, SSF_WIN95CLASSIC, FALSE);
  49. if ( lpState && cLength )
  50. {
  51. BOOL fReadFullPath = FALSE;
  52. //
  53. // Setup the default state of the structure and read in the current state
  54. // from the registry (over our freshly initialised structure).
  55. //
  56. state.cLength = SIZEOF(CABINETSTATE);
  57. state.nVersion = CABINETSTATE_VERSION;
  58. state.fSimpleDefault = TRUE;
  59. state.fFullPathTitle = FALSE;
  60. state.fSaveLocalView = TRUE;
  61. state.fNotShell = FALSE;
  62. state.fNewWindowMode = BOOLIFY(ss.fWin95Classic);
  63. state.fShowCompColor = FALSE;
  64. state.fDontPrettyNames = FALSE;
  65. state.fAdminsCreateCommonGroups = TRUE;
  66. state.fUnusedFlags = 0;
  67. state.fMenuEnumFilter = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
  68. if ( !GetSystemMetrics( SM_CLEANBOOT ) &&
  69. ERROR_SUCCESS == RegOpenKeyEx( HKEY_CURRENT_USER, c_szCabinetState, 0L, KEY_READ, &hKey ) )
  70. {
  71. DWORD dwFullPath=0;
  72. DWORD cbFullPath=SIZEOF(dwFullPath);
  73. fReadFromRegistry = ( ERROR_SUCCESS == SHQueryValueEx( hKey,
  74. c_szSettings,
  75. NULL,
  76. &dwType,
  77. (PVOID) &state, &cbData ) );
  78. if (ERROR_SUCCESS == SHQueryValueEx(hKey, c_szFullPath, NULL, NULL, (LPVOID)&dwFullPath, &cbFullPath))
  79. {
  80. fReadFullPath = TRUE;
  81. state.fFullPathTitle = (BOOL)dwFullPath ? TRUE : FALSE;
  82. }
  83. RegCloseKey( hKey );
  84. }
  85. //
  86. // Fix the structure if it is an early version and write back into the registry
  87. // to avoid having to do it again.
  88. //
  89. if ( fReadFromRegistry && state.nVersion < CABINETSTATE_VERSION )
  90. {
  91. // NT4 and IE4x had the same value for state.nVersion (1), and we have to stomp some of the flags
  92. // depending on whether we are pre-IE4x or not. To differentiate, we see if c_szFullPath was present.
  93. // This reg key was introduced only in IE40.
  94. if ( (state.nVersion < 1) || ((state.nVersion == 1) && !fReadFullPath) )
  95. {
  96. state.fNewWindowMode = BOOLIFY(ss.fWin95Classic);
  97. state.fAdminsCreateCommonGroups = TRUE; // Moved post BETA 2 SUR!
  98. state.fUnusedFlags = 0;
  99. state.fMenuEnumFilter = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
  100. }
  101. state.cLength = SIZEOF(CABINETSTATE);
  102. state.nVersion = CABINETSTATE_VERSION;
  103. WriteCabinetState( &state );
  104. }
  105. //
  106. // Copy only the requested data back to the caller.
  107. //
  108. state.cLength = (int) min( SIZEOF(CABINETSTATE), cLength );
  109. memcpy( lpState, &state, cLength );
  110. }
  111. return fReadFromRegistry;
  112. }
  113. // old export
  114. STDAPI_(BOOL) OldReadCabinetState( LPCABINETSTATE lpState, int cLength )
  115. {
  116. return ReadCabinetState(lpState, sizeof(CABINETSTATE));
  117. }
  118. /*----------------------------------------------------------------------------
  119. / Writes a CABINETSTATE structure back into the registry.
  120. /
  121. / Notes:
  122. / Attempt to do the right thing when given a small structure to write
  123. / back so that we don't mess up the users settings.
  124. /
  125. / In:
  126. / lpState -> structure to be written
  127. /
  128. / Out:
  129. / fSuccess = TRUE / FALSE indicating if state has been seralised
  130. /----------------------------------------------------------------------------*/
  131. STDAPI_(BOOL) WriteCabinetState(CABINETSTATE *lpState)
  132. {
  133. BOOL fSuccess = FALSE;
  134. if (lpState)
  135. {
  136. CABINETSTATE state;
  137. HKEY hKey;
  138. // Check to see if the structure is the right size, if its too small
  139. // then we must merge it with a real one before writing back!
  140. if (lpState->cLength < SIZEOF(CABINETSTATE))
  141. {
  142. ReadCabinetState(&state, SIZEOF(state));
  143. memcpy(&state, lpState, lpState->cLength);
  144. state.cLength = SIZEOF(CABINETSTATE);
  145. lpState = &state;
  146. }
  147. if ( ERROR_SUCCESS == RegCreateKey( HKEY_CURRENT_USER, c_szCabinetState, &hKey ) )
  148. {
  149. DWORD dwFullPath = lpState->fFullPathTitle ? TRUE : FALSE;
  150. fSuccess = ERROR_SUCCESS == RegSetValueEx( hKey,
  151. c_szSettings,
  152. 0,
  153. REG_BINARY,
  154. (LPVOID)lpState, (DWORD)SIZEOF(CABINETSTATE) );
  155. // NOTE: We have to continue writing this key. One of the uses for it is to decide
  156. // whether we are pre-IE4 or not. See ReadCabinetState()...
  157. RegSetValueEx(hKey, c_szFullPath, 0, REG_DWORD, (LPVOID)&dwFullPath, sizeof(dwFullPath));
  158. RegCloseKey( hKey );
  159. }
  160. }
  161. if (fSuccess)
  162. {
  163. // Notify anybody who is listening
  164. HANDLE hChange = SHGlobalCounterCreate(&GUID_FolderSettingsChange);
  165. SHGlobalCounterIncrement(hChange);
  166. SHGlobalCounterDestroy(hChange);
  167. }
  168. return fSuccess;
  169. }