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.

498 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. int iRetVal;
  194. iRetVal = swscanf ((LPCTSTR) Value, TEXT("%x"), &m_dwFlags);
  195. if (0 == iRetVal || EOF == iRetVal )
  196. {
  197. hr = E_INVALIDARG;
  198. goto LoadSec_CleanupAndQuit;
  199. }
  200. if ((m_dwFlags & REDIR_DONT_CARE) || (m_dwFlags & REDIR_FOLLOW_PARENT))
  201. {
  202. hr = S_OK;
  203. goto LoadSec_CleanupAndQuit;
  204. }
  205. //if we are here, there is more redirection path info. to be read off
  206. //of the ini file
  207. //so we first load the section
  208. do
  209. {
  210. cbCopied = GetPrivateProfileSection ((LPCTSTR) m_szEnglishDisplayName,
  211. lpszValue,
  212. cbSize,
  213. (LPCTSTR) IniFile
  214. );
  215. if (cbSize - 2 == cbCopied)
  216. {
  217. delete [] lpszValue;
  218. cbSize *= 2;
  219. lpszValue = new TCHAR [cbSize];
  220. continue;
  221. }
  222. break;
  223. } while (TRUE);
  224. //we now have the other section too.
  225. for (szEntry = lpszValue; *szEntry; szEntry += (lstrlen(szEntry) + 1))
  226. {
  227. Pair = szEntry;
  228. hr = SplitProfileString (Pair, Key, Val);
  229. Key.MakeLower(); //since CString comparison operator == is case
  230. //sensitive
  231. Insert (Key, Val, FALSE, FALSE);
  232. }
  233. hr = S_OK; //the section has been successfully loaded
  234. LoadSec_CleanupAndQuit:
  235. delete [] lpszValue;
  236. LoadSec_Quit:
  237. return hr;
  238. }
  239. //+--------------------------------------------------------------------------
  240. //
  241. // Member: CFileInfo::SaveSection
  242. //
  243. // Synopsis: this function saves the redir info. for the object to
  244. // the ini file on the sysvol
  245. //
  246. // Arguments: none
  247. //
  248. // Returns: ERROR_SUCCESS : if we were successful in saving
  249. // or other error codes
  250. //
  251. // History: 9/28/1998 RahulTh created
  252. //
  253. // Notes:
  254. //
  255. //---------------------------------------------------------------------------
  256. DWORD CFileInfo::SaveSection (void)
  257. {
  258. vector<CString>::iterator i;
  259. vector<CString>::iterator j;
  260. DWORD cbSize = 1024;
  261. TCHAR* lpszSection;
  262. CString szIniFile;
  263. CString szVal;
  264. BOOL bStatus;
  265. CFileInfo* pChildInfo;
  266. DWORD Status = ERROR_SUCCESS;
  267. //derive the name of the ini file
  268. szIniFile.LoadString (IDS_INIFILE);
  269. szIniFile = m_szFileRoot + '\\' + szIniFile;
  270. //create an empty section and write it to the ini file
  271. //so that the new data can be saved easily
  272. lpszSection = new TCHAR [cbSize];
  273. lpszSection[0] = lpszSection [1] = '\0';
  274. //pre-create the ini file in unicode so that the WritePrivateProfile*
  275. //APIs do not write in ANSI.
  276. PrecreateUnicodeIniFile ((LPCTSTR) szIniFile);
  277. bStatus = WritePrivateProfileSection ((LPCTSTR) m_szEnglishDisplayName,
  278. lpszSection,
  279. (LPCTSTR) szIniFile
  280. );
  281. //write the data into the FolderStatus section
  282. if (bStatus)
  283. {
  284. szVal.Format (TEXT("%x"), m_dwFlags);
  285. bStatus = WritePrivateProfileString (TEXT("FolderStatus"),
  286. (LPCTSTR) m_szEnglishDisplayName,
  287. (LPCTSTR) szVal,
  288. szIniFile
  289. );
  290. }
  291. if (bStatus)
  292. {
  293. for (i = m_RedirGroups.begin(), j = m_RedirPaths.begin();
  294. i != m_RedirGroups.end();
  295. i++, j++)
  296. {
  297. bStatus = WritePrivateProfileString ((LPCTSTR) m_szEnglishDisplayName,
  298. (LPCTSTR) (*i),
  299. (LPCTSTR) (*j),
  300. szIniFile
  301. );
  302. if (!bStatus)
  303. break;
  304. }
  305. }
  306. if (!bStatus)
  307. Status = GetLastError();
  308. else
  309. Status = ERROR_SUCCESS;
  310. delete [] lpszSection;
  311. return Status;
  312. }
  313. //+--------------------------------------------------------------------------
  314. //
  315. // Member: CFileInfo::Insert
  316. //
  317. // Synopsis: inserts a key value pair in the redir info structure of the
  318. // object. also note the description of the parameter fReplace
  319. //
  320. // Arguments: [in] szKey : the key
  321. // [in] szVal : the value
  322. // [in] fReplace : if FALSE, the key value pair won't be inserted
  323. // if another entry with the same key exists
  324. // [in] fSaveSection : save the section after insertions if true
  325. //
  326. // Returns: ERROR_SUCCESS : if the key value pair was inserted
  327. // ERROR_ALREADY_EXISTS : if the key value pair was not inserted
  328. // since another entry with the same key
  329. // already exists
  330. // or other error codes that might be encountered while saving
  331. // the section
  332. //
  333. // History: 9/28/1998 RahulTh created
  334. //
  335. // Notes: to keep the sysvol updated, it also calls SaveSection at the end
  336. //
  337. //---------------------------------------------------------------------------
  338. DWORD CFileInfo::Insert (const CString& szKey, const CString& szVal,
  339. BOOL fReplace, BOOL fSaveSection /*= TRUE*/)
  340. {
  341. vector<CString>::iterator i;
  342. vector<CString>::iterator j;
  343. CString Key;
  344. CString Val;
  345. DWORD Status = ERROR_SUCCESS;
  346. Key = szKey;
  347. Key.MakeLower();
  348. Val = szVal;
  349. //in this case, we must first check if an entry exists with that key
  350. for (i = m_RedirGroups.begin(), j = m_RedirPaths.begin();
  351. i != m_RedirGroups.end();
  352. i++, j++)
  353. {
  354. if (Key == *i)
  355. break;
  356. }
  357. if (m_RedirGroups.end() == i) //we do not have an entry with this key
  358. {
  359. m_RedirGroups.push_back(Key);
  360. m_RedirPaths.push_back (Val);
  361. }
  362. else //we do have an entry that matches the key
  363. {
  364. if (fReplace)
  365. *j = Key;
  366. else
  367. Status = ERROR_ALREADY_EXISTS;
  368. }
  369. if (ERROR_SUCCESS == Status && fSaveSection)
  370. Status = SaveSection();
  371. return Status;
  372. }
  373. //+--------------------------------------------------------------------------
  374. //
  375. // Member: CFileInfo::Delete
  376. //
  377. // Synopsis: deletes the entry corresponding to a given key
  378. //
  379. // Arguments: [in] szKey : the key that needs to get deleted
  380. //
  381. // Returns: ERROR_SUCCESS : if the deletion was successful
  382. // or other error codes that might be encountered while saving
  383. // the section (see notes below)
  384. //
  385. // History: 9/28/1998 RahulTh created
  386. //
  387. // Notes: to maintain the ini file on the sysvol in sync with the
  388. // snapin, we save the redir info. at the end of every deletion
  389. //
  390. //---------------------------------------------------------------------------
  391. DWORD CFileInfo::Delete (const CString& szKey, BOOL fSaveSection /*= TRUE*/)
  392. {
  393. vector<CString>::iterator i;
  394. vector<CString>::iterator j;
  395. DWORD Status = ERROR_SUCCESS;
  396. for (i = m_RedirGroups.begin(), j = m_RedirPaths.begin();
  397. i != m_RedirGroups.end();
  398. i++, j++)
  399. {
  400. if (szKey == *i)
  401. break;
  402. }
  403. if (m_RedirGroups.end() != i) //an entry with that key was found
  404. {
  405. m_RedirGroups.erase(i);
  406. m_RedirPaths.erase (j);
  407. if (fSaveSection)
  408. Status = SaveSection ();
  409. }
  410. return Status;
  411. }
  412. //+--------------------------------------------------------------------------
  413. //
  414. // Member: CFileInfo::DeleteAllItems
  415. //
  416. // Synopsis: this functions deletes all the group and path information
  417. // stored in the object
  418. //
  419. // Arguments: none
  420. //
  421. // Returns: nothing
  422. //
  423. // History: 10/1/1998 RahulTh created
  424. //
  425. // Notes:
  426. //
  427. //---------------------------------------------------------------------------
  428. void CFileInfo::DeleteAllItems (void)
  429. {
  430. m_RedirGroups.erase (m_RedirGroups.begin(), m_RedirGroups.end());
  431. m_RedirPaths.erase (m_RedirPaths.begin(), m_RedirPaths.end());
  432. }