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.

264 lines
5.7 KiB

  1. //*************************************************************
  2. //
  3. // Copyright (c) Microsoft Corporation 1998
  4. // All rights reserved
  5. //
  6. // cspath.cxx
  7. //
  8. // Class for building and setting the ClassStore path in the
  9. // registry.
  10. //
  11. //*************************************************************
  12. #include "appmgext.hxx"
  13. CSPath::CSPath()
  14. {
  15. _pwszPath = 0;
  16. }
  17. CSPath::~CSPath()
  18. {
  19. if ( _pwszPath )
  20. LocalFree( _pwszPath );
  21. }
  22. DWORD
  23. CSPath::AddComponent(
  24. WCHAR * pwszDSPath,
  25. WCHAR * pwszDisplayName
  26. )
  27. {
  28. WCHAR * pwszCSPath;
  29. WCHAR * pwszNewPath;
  30. DWORD Size;
  31. HRESULT hr;
  32. DWORD Status;
  33. if ( ! pwszDSPath )
  34. return ERROR_SUCCESS;
  35. hr = CsGetClassStorePath( pwszDSPath, &pwszCSPath );
  36. if ( hr != S_OK )
  37. {
  38. //
  39. // This call was simply a string manipulation, it should
  40. // only fail due to out of memory
  41. //
  42. DebugMsg((DM_VERBOSE, IDS_NO_CLASSSTORE, pwszDisplayName, hr));
  43. return (DWORD) hr;
  44. }
  45. Size = 0;
  46. if ( _pwszPath )
  47. Size += lstrlen(_pwszPath) * sizeof(WCHAR);
  48. Size += (lstrlen(pwszCSPath) + 2) * sizeof(WCHAR);
  49. pwszNewPath = (WCHAR *) LocalAlloc( 0, Size );
  50. if ( ! pwszNewPath )
  51. {
  52. Status = ERROR_NOT_ENOUGH_MEMORY;
  53. }
  54. else
  55. {
  56. hr = StringCchCopy( pwszNewPath, Size, pwszCSPath );
  57. if (FAILED(hr))
  58. {
  59. LocalFree(pwszNewPath);
  60. Status = HRESULT_CODE(hr);
  61. }
  62. else
  63. {
  64. hr = StringCchCat( pwszNewPath, Size, L";" );
  65. if (SUCCEEDED(hr))
  66. {
  67. if ( _pwszPath )
  68. {
  69. hr = StringCchCat( pwszNewPath, Size, _pwszPath );
  70. }
  71. }
  72. if (FAILED(hr))
  73. {
  74. LocalFree(pwszNewPath);
  75. Status = HRESULT_CODE(hr);
  76. }
  77. else
  78. {
  79. LocalFree( _pwszPath );
  80. _pwszPath = pwszNewPath;
  81. Status = ERROR_SUCCESS;
  82. }
  83. }
  84. }
  85. LocalFree( pwszCSPath );
  86. return Status;
  87. }
  88. DWORD
  89. CSPath::Commit(
  90. HANDLE hToken
  91. )
  92. {
  93. DWORD Status;
  94. if ( _pwszPath )
  95. {
  96. Status = WriteClassStorePath(hToken, _pwszPath);
  97. DebugMsg((DM_VERBOSE, IDS_CSPATH, _pwszPath));
  98. }
  99. else
  100. {
  101. (void) WriteClassStorePath(hToken, L"");
  102. Status = CS_E_NO_CLASSSTORE;
  103. DebugMsg((DM_VERBOSE, IDS_NOCSPATH));
  104. }
  105. return Status;
  106. }
  107. DWORD
  108. CSPath::WriteClassStorePath(
  109. HANDLE hToken,
  110. LPWSTR pwszClassStorePath
  111. )
  112. {
  113. DWORD err;
  114. LPWSTR wszIniFilePath;
  115. HRESULT hr;
  116. DWORD dwSize;
  117. err = GetScriptDirPath(
  118. hToken,
  119. sizeof(APPMGMT_INI_FILENAME) / sizeof(WCHAR),
  120. &wszIniFilePath,
  121. &dwSize);
  122. if (ERROR_SUCCESS != err)
  123. {
  124. return err;
  125. }
  126. hr = StringCchCat(wszIniFilePath, dwSize, APPMGMT_INI_FILENAME);
  127. if (FAILED(hr))
  128. {
  129. err = HRESULT_CODE(hr);
  130. }
  131. if (ERROR_SUCCESS == err)
  132. {
  133. err = WriteClassStorePathToFile(
  134. wszIniFilePath,
  135. pwszClassStorePath);
  136. }
  137. delete [] wszIniFilePath;
  138. return err;
  139. }
  140. LONG
  141. CSPath::WriteClassStorePathToFile(
  142. WCHAR* wszIniFilePath,
  143. WCHAR* wszClassStorePath
  144. )
  145. {
  146. HANDLE hFile;
  147. BOOL bStatus;
  148. DWORD dwWritten;
  149. //
  150. // This method attempts to write the class store path
  151. // into a file in a non-roaming portion of the user's profile.
  152. //
  153. // The format of the file is simple: it is a sequence of unicode
  154. // characters terminated by a null unicode character -- i.e.,
  155. // its contents are simply the exact bytes of the wszClassStorePath
  156. // parameter, including the terminating character.
  157. //
  158. // Clients reading the file should verify that the very last character
  159. // of the file is a null terminator in order to detect corrupt files.
  160. //
  161. //
  162. // First, attempt to open the file, creating it if it does not exist
  163. //
  164. hFile = CreateFile(
  165. wszIniFilePath,
  166. GENERIC_WRITE,
  167. 0, // do not allow anyone else access while we are modifying the file
  168. NULL,
  169. CREATE_ALWAYS,
  170. FILE_ATTRIBUTE_SYSTEM,
  171. NULL);
  172. //
  173. // If we can't create the file, we have failed
  174. //
  175. if ( INVALID_HANDLE_VALUE == hFile )
  176. {
  177. return GetLastError();
  178. }
  179. LONG Status;
  180. Status = ERROR_SUCCESS;
  181. //
  182. // Now erease the data in it -- truncate the file to the current file pointer,
  183. // which is at the beginning of the file
  184. //
  185. bStatus = SetEndOfFile( hFile );
  186. //
  187. // If we cannot erase the current contents, this is a failure
  188. //
  189. if ( ! bStatus )
  190. {
  191. Status = GetLastError();
  192. goto cleanup_and_exit;
  193. }
  194. //
  195. // Now write the class store path into the file -- we simply do a memory copy
  196. // of the string into the file
  197. //
  198. bStatus = WriteFile(
  199. hFile,
  200. wszClassStorePath,
  201. ( lstrlen(wszClassStorePath) + 1 ) * sizeof(*wszClassStorePath),
  202. &dwWritten,
  203. NULL);
  204. //
  205. // If the write failed, find out why and return that status
  206. //
  207. if ( ! bStatus )
  208. {
  209. Status = GetLastError();
  210. }
  211. cleanup_and_exit:
  212. //
  213. // Free our file resource since its no longer needed
  214. //
  215. CloseHandle( hFile );
  216. //
  217. // Everything worked, we return a success code
  218. //
  219. return Status;
  220. }