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.

192 lines
5.9 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: allcmdir.cpp
  4. //
  5. // Module: CMCFG32.DLL and CMSTP.EXE
  6. //
  7. // Synopsis: Implementation of GetAllUsersCmDir
  8. //
  9. // Copyright (c) 1999 Microsoft Corporation
  10. //
  11. // Author: quintinb Created Header 08/19/99
  12. //
  13. //+----------------------------------------------------------------------------
  14. //+----------------------------------------------------------------------------
  15. //
  16. // Function: GetAllUsersCmDir
  17. //
  18. // Synopsis: This function fills in the string passed in with the path to the
  19. // path where CM should be installed. For instance, it should return
  20. // c:\Documents and Settings\All Users\Application Data\Microsoft\Network\Connections\Cm
  21. //
  22. // Arguments: LPTSTR pszDir - String to the Users Connection Manager Directory
  23. //
  24. // Returns: LPTSTR - String to the Users Connection Manager Directory
  25. //
  26. // History: quintinb Created Header 2/19/98
  27. //
  28. //+----------------------------------------------------------------------------
  29. BOOL GetAllUsersCmDir(LPTSTR pszDir, HINSTANCE hInstance)
  30. {
  31. MYDBGASSERT(pszDir);
  32. pszDir[0] = TEXT('\0');
  33. LPMALLOC pMalloc;
  34. HRESULT hr = SHGetMalloc(&pMalloc);
  35. if (FAILED (hr))
  36. {
  37. CMASSERTMSG(FALSE, TEXT("Failed to get a Shell Malloc Pointer."));
  38. return FALSE;
  39. }
  40. TCHAR szCmSubFolder[MAX_PATH+1];
  41. TCHAR szAppData[MAX_PATH+1];
  42. TCHAR szDesktop[MAX_PATH+1];
  43. LPITEMIDLIST pidl;
  44. BOOL bReturn = FALSE;
  45. //
  46. // We really want the Common App Data dir, but this CSIDL value is only supported on
  47. // NT5 so far. If this succeeds, we only need to append the path to it.
  48. //
  49. hr = SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_APPDATA, &pidl);
  50. if (SUCCEEDED(hr))
  51. {
  52. if (!SHGetPathFromIDList(pidl, pszDir))
  53. {
  54. CMASSERTMSG(FALSE, TEXT("GetAllUsersCmDir -- SHGetPathFromIDList Failed to retrieve CSIDL_COMMON_APPDATA"));
  55. goto exit;
  56. }
  57. pMalloc->Free(pidl);
  58. pidl = NULL;
  59. }
  60. else
  61. {
  62. //
  63. // Of course, things aren't always that easy, lets try getting the regular
  64. // Application Data dir. We can hopefully combine the returns from two
  65. // CSIDL's like CSIDL_APPDATA and CSIDL_COMMON_DESKTOPDIRECTORY to acheive the
  66. // same affect on older machines.
  67. //
  68. hr = SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pidl);
  69. if (SUCCEEDED(hr))
  70. {
  71. if (!SHGetPathFromIDList(pidl, szAppData))
  72. {
  73. goto exit;
  74. }
  75. pMalloc->Free(pidl);
  76. pidl = NULL;
  77. }
  78. else
  79. {
  80. //
  81. // CSIDL_APPDATA isn't even supported on win95 gold
  82. //
  83. MYVERIFY(0 != LoadString(hInstance, IDS_APPDATA, szAppData, MAX_PATH));
  84. }
  85. //
  86. // Now lets try to get the Common Desktop Directory to combine the two
  87. //
  88. BOOL bCommonFound = FALSE;
  89. hr = SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, &pidl);
  90. if (SUCCEEDED(hr))
  91. {
  92. if (SHGetPathFromIDList(pidl, szDesktop))
  93. {
  94. bCommonFound = TRUE;
  95. }
  96. pMalloc->Free(pidl);
  97. pidl = NULL;
  98. }
  99. if (!bCommonFound)
  100. {
  101. //
  102. // Okay, next lets try the Reg Key for the common desktop directory.
  103. // (Win98 gold with profiling contains the reg key but the CSIDL fails)
  104. //
  105. const TCHAR* const c_pszRegShellFolders = TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders");
  106. const TCHAR* const c_pszRegCommonDesktop = TEXT("Common Desktop");
  107. HKEY hKey;
  108. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_pszRegShellFolders,
  109. 0, KEY_READ, &hKey))
  110. {
  111. DWORD dwSize = MAX_PATH;
  112. DWORD dwType = REG_SZ;
  113. if (ERROR_SUCCESS == RegQueryValueEx(hKey, c_pszRegCommonDesktop,
  114. NULL, &dwType, (LPBYTE)szDesktop,
  115. &dwSize))
  116. {
  117. bCommonFound = TRUE;
  118. }
  119. RegCloseKey(hKey);
  120. }
  121. }
  122. if (!bCommonFound)
  123. {
  124. //
  125. // As a fall back lets try the windows directory, NTRAID 374912
  126. //
  127. if (GetWindowsDirectory(szDesktop, MAX_PATH))
  128. {
  129. //
  130. // Then we have the windows directory, but we need to append
  131. // \\Desktop so that the parsing logic which follows parses
  132. // this correctly. It is expecting the path to the desktop dir
  133. // not a path to the windows dir (if we didn't we would end up with
  134. // c:\Application Data instead of c:\windows\Application data as we
  135. // want and expect). Note that there is no need to worry about
  136. // localization of Desktop because we are going to remove it anyway.
  137. //
  138. lstrcat(szDesktop, TEXT("\\Desktop"));
  139. }
  140. }
  141. CFileNameParts AppData(szAppData);
  142. CFileNameParts CommonDesktop(szDesktop);
  143. wsprintf(pszDir, TEXT("%s%s%s"), CommonDesktop.m_Drive, CommonDesktop.m_Dir,
  144. AppData.m_FileName, AppData.m_Extension);
  145. }
  146. //
  147. // Now append the CM sub directory structure
  148. //
  149. if (!LoadString(hInstance, IDS_CMSUBFOLDER, szCmSubFolder, MAX_PATH))
  150. {
  151. goto exit;
  152. }
  153. MYVERIFY(NULL != lstrcat(pszDir, szCmSubFolder));
  154. bReturn = TRUE;
  155. exit:
  156. //
  157. // Free the allocated pidl if necessary
  158. //
  159. if (pidl)
  160. {
  161. pMalloc->Free(pidl);
  162. }
  163. //
  164. // release the shell's IMalloc ptr
  165. //
  166. pMalloc->Release();
  167. return bReturn;
  168. }