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.

491 lines
14 KiB

  1. /*++
  2. Microsoft Windows
  3. Copyright (C) Microsoft Corporation, 1994 - 1998.
  4. Module Name:
  5. FileInfo.cxx
  6. Abstract:
  7. This file contains the methods of the class CFileInfo. This is the class
  8. of objects that are used by the code to keep track of files/folders that
  9. are displayed in the MMC snapin.
  10. Author:
  11. Rahul Thombre (RahulTh) 4/5/1998
  12. Revision History:
  13. 4/5/1998 RahulTh Created this module.
  14. 6/22/1998 RahulTh added comments.
  15. --*/
  16. #include "precomp.hxx"
  17. //static members
  18. UINT CFileInfo::class_res_id = IDS_DIRS_START; //since we have an array of structures for the folders
  19. //in the same order as the resource ids of their names
  20. //we can use this static member to figure out the cookie
  21. //for each folder in the constructor. This ensures
  22. //that the default flags are set properly
  23. WCHAR * g_szEnglishNames [] =
  24. {
  25. L"Application Data",
  26. L"Desktop",
  27. L"My Documents",
  28. L"Start Menu",
  29. L"My Pictures",
  30. L"Programs",
  31. L"Startup"
  32. };
  33. //////////////////////////////////////////////
  34. // Construction
  35. //
  36. // initializes the members of this class to some default values
  37. //////////////////////////////////////////////
  38. CFileInfo::CFileInfo(LPCTSTR lpszFullPathname /*= NULL*/
  39. )
  40. {
  41. m_pRedirPage = NULL;
  42. m_pSettingsPage = NULL;
  43. m_bSettingsInitialized = FALSE;
  44. m_bHideChildren = TRUE;
  45. Initialize (class_res_id, //use a random cookie for the time being
  46. NULL //for now, we use a null path for the file root.
  47. );
  48. class_res_id++;
  49. }
  50. /////////////////////////////////////
  51. // Destruction
  52. //
  53. CFileInfo::~CFileInfo()
  54. {
  55. //clean up here... if there is anything to clean up in this class
  56. DeleteAllItems();
  57. }
  58. /////////////////////////////////////////////////////////////
  59. // this routine set the scope item id for the node in its object
  60. //
  61. void CFileInfo::SetScopeItemID (IN LONG scopeID)
  62. {
  63. m_scopeID = scopeID;
  64. }
  65. /////////////////////////////////////////////////////////////
  66. // this routine sets the default values on most of the members of this class
  67. //
  68. void CFileInfo::Initialize (long cookie, LPCTSTR szGPTPath)
  69. {
  70. SHFILEINFO fileInfo;
  71. CString szTmp;
  72. CString szExt;
  73. LONG i;
  74. i = GETINDEX (cookie);
  75. //set the cookie
  76. m_cookie = cookie;
  77. //set the file root
  78. if (szGPTPath)
  79. m_szFileRoot = szGPTPath;
  80. else
  81. m_szFileRoot.Empty();
  82. //set the name and type.
  83. m_szDisplayname = TEXT("???");
  84. m_szRelativePath = TEXT ("???");
  85. m_szTypename.LoadString (IDS_FOLDER_TYPE);
  86. if (-1 != i)
  87. {
  88. m_szDisplayname.LoadString (m_cookie);
  89. m_szEnglishDisplayName = g_szEnglishNames[i];
  90. m_szTypename.LoadString (IDS_FOLDER_TYPE);
  91. m_dwFlags = REDIR_DONT_CARE;
  92. switch (m_cookie)
  93. {
  94. case IDS_MYPICS:
  95. m_szRelativePath.LoadString (IDS_MYPICS_RELPATH);
  96. break;
  97. case IDS_PROGRAMS:
  98. m_szRelativePath.LoadString (IDS_PROGRAMS_RELPATH);
  99. break;
  100. case IDS_STARTUP:
  101. m_szRelativePath.LoadString (IDS_STARTUP_RELPATH);
  102. break;
  103. default:
  104. m_szRelativePath = m_szDisplayname;
  105. break;
  106. }
  107. }
  108. }
  109. //+--------------------------------------------------------------------------
  110. //
  111. // Member: CFileInfo::LoadSection
  112. //
  113. // Synopsis: This member function loads the redirection info. for this
  114. // folder from the ini file
  115. //
  116. // Arguments: none
  117. //
  118. // Returns: S_OK : if the section was loaded successfully
  119. // or other error codes
  120. //
  121. // History: 9/28/1998 RahulTh created
  122. //
  123. // Notes:
  124. //
  125. //---------------------------------------------------------------------------
  126. HRESULT CFileInfo::LoadSection (void)
  127. {
  128. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  129. LONG i;
  130. BOOL bStatus;
  131. DWORD Status;
  132. const TCHAR lpszDefault[] = TEXT("*"); //a random default value
  133. DWORD cbSize = 1024;
  134. DWORD cbCopied;
  135. TCHAR* lpszValue;
  136. TCHAR* szEntry;
  137. CString IniFile;
  138. CString Value;
  139. BOOL bValueFound;
  140. HRESULT hr;
  141. CString Pair;
  142. CString Key;
  143. CString Val;
  144. i = GETINDEX (m_cookie);
  145. if (-1 == i)
  146. {
  147. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  148. goto LoadSec_Quit;
  149. }
  150. //get the name of the ini file
  151. IniFile.LoadString (IDS_INIFILE);
  152. IniFile = m_szFileRoot + '\\' + IniFile;
  153. m_dwFlags = REDIR_DONT_CARE; //set the default value
  154. m_RedirGroups.erase (m_RedirGroups.begin(), m_RedirGroups.end());
  155. m_RedirPaths.erase (m_RedirPaths.begin(), m_RedirPaths.end());
  156. //read in the data from the FolderStatus section
  157. do
  158. {
  159. lpszValue = new TCHAR [cbSize];
  160. //set it to something other than the default value
  161. lpszValue[0] = '+';
  162. lpszValue[1] = '\0';
  163. //now try to read it from the ini file
  164. cbCopied = GetPrivateProfileString (TEXT("FolderStatus"),
  165. m_szEnglishDisplayName,
  166. lpszDefault,
  167. lpszValue,
  168. cbSize,
  169. (LPCTSTR) IniFile
  170. );
  171. if ('*' == lpszValue[0]) //the default string was copied, so the key does not exist
  172. {
  173. bValueFound = FALSE;
  174. break;
  175. }
  176. if (cbSize - 1 == cbCopied)
  177. {
  178. delete [] lpszValue;
  179. cbSize *= 2;
  180. continue;
  181. }
  182. bValueFound = TRUE;
  183. break;
  184. } while (TRUE);
  185. if (!bValueFound)
  186. {
  187. hr = S_OK;
  188. goto LoadSec_CleanupAndQuit;
  189. }
  190. Value = lpszValue;
  191. Value.TrimLeft();
  192. Value.TrimRight();
  193. swscanf ((LPCTSTR) Value, TEXT("%x"), &m_dwFlags);
  194. if ((m_dwFlags & REDIR_DONT_CARE) || (m_dwFlags & REDIR_FOLLOW_PARENT))
  195. {
  196. hr = S_OK;
  197. goto LoadSec_CleanupAndQuit;
  198. }
  199. //if we are here, there is more redirection path info. to be read off
  200. //of the ini file
  201. //so we first load the section
  202. do
  203. {
  204. cbCopied = GetPrivateProfileSection ((LPCTSTR) m_szEnglishDisplayName,
  205. lpszValue,
  206. cbSize,
  207. (LPCTSTR) IniFile
  208. );
  209. if (cbSize - 2 == cbCopied)
  210. {
  211. delete [] lpszValue;
  212. cbSize *= 2;
  213. lpszValue = new TCHAR [cbSize];
  214. continue;
  215. }
  216. break;
  217. } while (TRUE);
  218. //we now have the other section too.
  219. for (szEntry = lpszValue; *szEntry; szEntry += (lstrlen(szEntry) + 1))
  220. {
  221. Pair = szEntry;
  222. hr = SplitProfileString (Pair, Key, Val);
  223. Key.MakeLower(); //since CString comparison operator == is case
  224. //sensitive
  225. Insert (Key, Val, FALSE, FALSE);
  226. }
  227. hr = S_OK; //the section has been successfully loaded
  228. LoadSec_CleanupAndQuit:
  229. delete [] lpszValue;
  230. LoadSec_Quit:
  231. return hr;
  232. }
  233. //+--------------------------------------------------------------------------
  234. //
  235. // Member: CFileInfo::SaveSection
  236. //
  237. // Synopsis: this function saves the redir info. for the object to
  238. // the ini file on the sysvol
  239. //
  240. // Arguments: none
  241. //
  242. // Returns: ERROR_SUCCESS : if we were successful in saving
  243. // or other error codes
  244. //
  245. // History: 9/28/1998 RahulTh created
  246. //
  247. // Notes:
  248. //
  249. //---------------------------------------------------------------------------
  250. DWORD CFileInfo::SaveSection (void)
  251. {
  252. vector<CString>::iterator i;
  253. vector<CString>::iterator j;
  254. DWORD cbSize = 1024;
  255. TCHAR* lpszSection;
  256. CString szIniFile;
  257. CString szVal;
  258. BOOL bStatus;
  259. CFileInfo* pChildInfo;
  260. DWORD Status = ERROR_SUCCESS;
  261. //derive the name of the ini file
  262. szIniFile.LoadString (IDS_INIFILE);
  263. szIniFile = m_szFileRoot + '\\' + szIniFile;
  264. //create an empty section and write it to the ini file
  265. //so that the new data can be saved easily
  266. lpszSection = new TCHAR [cbSize];
  267. lpszSection[0] = lpszSection [1] = '\0';
  268. //pre-create the ini file in unicode so that the WritePrivateProfile*
  269. //APIs do not write in ANSI.
  270. PrecreateUnicodeIniFile ((LPCTSTR) szIniFile);
  271. bStatus = WritePrivateProfileSection ((LPCTSTR) m_szEnglishDisplayName,
  272. lpszSection,
  273. (LPCTSTR) szIniFile
  274. );
  275. //write the data into the FolderStatus section
  276. if (bStatus)
  277. {
  278. szVal.Format (TEXT("%x"), m_dwFlags);
  279. bStatus = WritePrivateProfileString (TEXT("FolderStatus"),
  280. (LPCTSTR) m_szEnglishDisplayName,
  281. (LPCTSTR) szVal,
  282. szIniFile
  283. );
  284. }
  285. if (bStatus)
  286. {
  287. for (i = m_RedirGroups.begin(), j = m_RedirPaths.begin();
  288. i != m_RedirGroups.end();
  289. i++, j++)
  290. {
  291. bStatus = WritePrivateProfileString ((LPCTSTR) m_szEnglishDisplayName,
  292. (LPCTSTR) (*i),
  293. (LPCTSTR) (*j),
  294. szIniFile
  295. );
  296. if (!bStatus)
  297. break;
  298. }
  299. }
  300. if (!bStatus)
  301. Status = GetLastError();
  302. else
  303. Status = ERROR_SUCCESS;
  304. delete [] lpszSection;
  305. return Status;
  306. }
  307. //+--------------------------------------------------------------------------
  308. //
  309. // Member: CFileInfo::Insert
  310. //
  311. // Synopsis: inserts a key value pair in the redir info structure of the
  312. // object. also note the description of the parameter fReplace
  313. //
  314. // Arguments: [in] szKey : the key
  315. // [in] szVal : the value
  316. // [in] fReplace : if FALSE, the key value pair won't be inserted
  317. // if another entry with the same key exists
  318. // [in] fSaveSection : save the section after insertions if true
  319. //
  320. // Returns: ERROR_SUCCESS : if the key value pair was inserted
  321. // ERROR_ALREADY_EXISTS : if the key value pair was not inserted
  322. // since another entry with the same key
  323. // already exists
  324. // or other error codes that might be encountered while saving
  325. // the section
  326. //
  327. // History: 9/28/1998 RahulTh created
  328. //
  329. // Notes: to keep the sysvol updated, it also calls SaveSection at the end
  330. //
  331. //---------------------------------------------------------------------------
  332. DWORD CFileInfo::Insert (const CString& szKey, const CString& szVal,
  333. BOOL fReplace, BOOL fSaveSection /*= TRUE*/)
  334. {
  335. vector<CString>::iterator i;
  336. vector<CString>::iterator j;
  337. CString Key;
  338. CString Val;
  339. DWORD Status = ERROR_SUCCESS;
  340. Key = szKey;
  341. Key.MakeLower();
  342. Val = szVal;
  343. //in this case, we must first check if an entry exists with that key
  344. for (i = m_RedirGroups.begin(), j = m_RedirPaths.begin();
  345. i != m_RedirGroups.end();
  346. i++, j++)
  347. {
  348. if (Key == *i)
  349. break;
  350. }
  351. if (m_RedirGroups.end() == i) //we do not have an entry with this key
  352. {
  353. m_RedirGroups.push_back(Key);
  354. m_RedirPaths.push_back (Val);
  355. }
  356. else //we do have an entry that matches the key
  357. {
  358. if (fReplace)
  359. *j = Key;
  360. else
  361. Status = ERROR_ALREADY_EXISTS;
  362. }
  363. if (ERROR_SUCCESS == Status && fSaveSection)
  364. Status = SaveSection();
  365. return Status;
  366. }
  367. //+--------------------------------------------------------------------------
  368. //
  369. // Member: CFileInfo::Delete
  370. //
  371. // Synopsis: deletes the entry corresponding to a given key
  372. //
  373. // Arguments: [in] szKey : the key that needs to get deleted
  374. //
  375. // Returns: ERROR_SUCCESS : if the deletion was successful
  376. // or other error codes that might be encountered while saving
  377. // the section (see notes below)
  378. //
  379. // History: 9/28/1998 RahulTh created
  380. //
  381. // Notes: to maintain the ini file on the sysvol in sync with the
  382. // snapin, we save the redir info. at the end of every deletion
  383. //
  384. //---------------------------------------------------------------------------
  385. DWORD CFileInfo::Delete (const CString& szKey, BOOL fSaveSection /*= TRUE*/)
  386. {
  387. vector<CString>::iterator i;
  388. vector<CString>::iterator j;
  389. DWORD Status = ERROR_SUCCESS;
  390. for (i = m_RedirGroups.begin(), j = m_RedirPaths.begin();
  391. i != m_RedirGroups.end();
  392. i++, j++)
  393. {
  394. if (szKey == *i)
  395. break;
  396. }
  397. if (m_RedirGroups.end() != i) //an entry with that key was found
  398. {
  399. m_RedirGroups.erase(i);
  400. m_RedirPaths.erase (j);
  401. if (fSaveSection)
  402. Status = SaveSection ();
  403. }
  404. return Status;
  405. }
  406. //+--------------------------------------------------------------------------
  407. //
  408. // Member: CFileInfo::DeleteAllItems
  409. //
  410. // Synopsis: this functions deletes all the group and path information
  411. // stored in the object
  412. //
  413. // Arguments: none
  414. //
  415. // Returns: nothing
  416. //
  417. // History: 10/1/1998 RahulTh created
  418. //
  419. // Notes:
  420. //
  421. //---------------------------------------------------------------------------
  422. void CFileInfo::DeleteAllItems (void)
  423. {
  424. m_RedirGroups.erase (m_RedirGroups.begin(), m_RedirGroups.end());
  425. m_RedirPaths.erase (m_RedirPaths.begin(), m_RedirPaths.end());
  426. }