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.

344 lines
11 KiB

  1. /*++
  2. Copyright (C) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. PERSISTCFG.cpp
  5. Abstract:
  6. This file implements the WinMgmt persistent configuration operations.
  7. Classes implemented:
  8. CPersistentConfig persistent configuration manager
  9. History:
  10. 1/13/98 paulall Created.
  11. --*/
  12. #include "precomp.h"
  13. #include <sync.h>
  14. #include <memory.h>
  15. #include <stdio.h>
  16. #include "PersistCfg.h"
  17. #include "reg.h"
  18. #define WinMgmt_CFG_ACTUAL __TEXT("$WinMgmt.CFG")
  19. #define WinMgmt_CFG_PENDING __TEXT("$WinMgmt.$FG")
  20. #define WinMgmt_CFG_BACKUP __TEXT("$WinMgmt.CFG.BAK")
  21. CDirectoryPath CPersistentConfig::m_Directory;
  22. /*=============================================================================
  23. * CDirectoryPath::CDirectoryPath
  24. *
  25. * Initialised the directory path
  26. *
  27. *=============================================================================
  28. */
  29. CDirectoryPath::CDirectoryPath()
  30. {
  31. Registry r(WBEM_REG_WINMGMT);
  32. OnDeleteIf0<void(*)(void),&CStaticCritSec::SetFailure> Fail;
  33. pszDirectory = NULL;
  34. if (r.GetStr(__TEXT("Repository Directory"), &pszDirectory))
  35. {
  36. size_t sizeString = MAX_PATH + LENGTH_OF(__TEXT("\\wbem\\repository"));
  37. wmilib::auto_buffer<TCHAR> pWindir(new TCHAR[sizeString]);
  38. if (NULL == pWindir.get()) return;
  39. UINT ReqSize = GetSystemDirectory(pWindir.get(),MAX_PATH+1);
  40. if (ReqSize > MAX_PATH)
  41. {
  42. sizeString = ReqSize + LENGTH_OF(__TEXT("\\wbem\\repository"));
  43. pWindir.reset(new TCHAR[sizeString]);
  44. if (NULL == pWindir.get()) return;
  45. if (0 == GetSystemDirectory(pWindir.get(),ReqSize+1)) return;
  46. }
  47. StringCchCat(pWindir.get(),sizeString,__TEXT("\\wbem\\repository"));
  48. r.SetExpandStr(__TEXT("Repository Directory"),__TEXT("%systemroot%\\system32\\wbem\\repository"));
  49. TCHAR * pDiscard = NULL;
  50. if (r.GetStr(__TEXT("Working Directory"), &pDiscard))
  51. {
  52. r.SetExpandStr(__TEXT("Working Directory"),__TEXT("%systemroot%\\system32\\wbem"));
  53. }
  54. delete [] pDiscard;
  55. pszDirectory = pWindir.release();
  56. Fail.dismiss();
  57. return;
  58. }
  59. Fail.dismiss();
  60. }
  61. /*=============================================================================
  62. * GetPersistentCfgValue
  63. *
  64. * Retrieves the configuration from the configuration file if it
  65. * has not yet been retrieved into memory, or retrieves it from a
  66. * memory cache.
  67. *
  68. * Parameters:
  69. * dwOffset needs to be less than MaxNumberConfigEntries and specifies
  70. * the configuration entry required.
  71. * dwValue if sucessful this will contain the value. If the value
  72. * has not been set this will return 0.
  73. *
  74. * Return value:
  75. * BOOL returns TRUE if successful.
  76. *=============================================================================
  77. */
  78. BOOL CPersistentConfig::GetPersistentCfgValue(DWORD dwOffset, DWORD &dwValue)
  79. {
  80. dwValue = 0;
  81. if (dwOffset >= MaxNumberConfigEntries)
  82. return FALSE;
  83. //Try and read the file if it exists, otherwise it does not matter, we just
  84. wmilib::auto_buffer<TCHAR> pszFilename( GetFullFilename(WinMgmt_CFG_ACTUAL));
  85. if (NULL == pszFilename.get()) return FALSE;
  86. HANDLE hFile = CreateFile(pszFilename.get(), //Name of file
  87. GENERIC_READ, //Read only at
  88. 0, //Don't need to allow anyone else in
  89. 0, //Shouldn't need security
  90. OPEN_EXISTING, //Only open the file if it exists
  91. 0, //No attributes needed
  92. 0); //No template file required
  93. if (hFile != INVALID_HANDLE_VALUE)
  94. {
  95. DWORD dwNumBytesRead;
  96. if ((GetFileSize(hFile, NULL) >= sizeof(DWORD)*(dwOffset+1)) &&
  97. (SetFilePointer (hFile, sizeof(DWORD)*dwOffset, 0, FILE_BEGIN) != INVALID_SET_FILE_POINTER) &&
  98. ReadFile(hFile, &dwValue, sizeof(DWORD), &dwNumBytesRead, NULL))
  99. {
  100. }
  101. CloseHandle(hFile);
  102. }
  103. return TRUE;
  104. }
  105. /*=============================================================================
  106. * WriteConfig
  107. *
  108. * Writes the $WinMgmt.CFG file into the memory cache and to the file. It
  109. * protects the existing file until the last minute.
  110. *
  111. * return value:
  112. * BOOL returns TRUE if successful.
  113. *=============================================================================
  114. */
  115. BOOL CPersistentConfig::SetPersistentCfgValue(DWORD dwOffset, DWORD dwValue)
  116. {
  117. if (dwOffset >= MaxNumberConfigEntries)
  118. return FALSE;
  119. BOOL bRet = FALSE;
  120. wmilib::auto_buffer<TCHAR> pszActual(GetFullFilename(WinMgmt_CFG_ACTUAL));
  121. if (NULL == pszActual.get()) return FALSE;
  122. //Create a new file to write to...
  123. HANDLE hFile = CreateFile(pszActual.get(), //Name of file
  124. GENERIC_WRITE | GENERIC_READ ,
  125. 0, //Don't need to allow anyone else in
  126. 0, //Shouldn't need security
  127. OPEN_ALWAYS, //create if does not exist
  128. 0, //No attributes needed
  129. 0); //No template file required
  130. if (hFile != INVALID_HANDLE_VALUE)
  131. {
  132. DWORD dwNumBytesWritten;
  133. DWORD dwNumBytesReaded;
  134. DWORD lowSize = GetFileSize(hFile, NULL);
  135. if (GetFileSize(hFile, NULL) != MaxNumberConfigEntries*sizeof(DWORD))
  136. {
  137. DWORD buff[MaxNumberConfigEntries]={0};
  138. ReadFile(hFile, buff, sizeof(buff), &dwNumBytesWritten, NULL);
  139. buff[dwOffset] = dwValue;
  140. if (SetFilePointer(hFile,0,0, FILE_BEGIN)!=INVALID_SET_FILE_POINTER)
  141. {
  142. bRet = WriteFile(hFile, buff, sizeof(buff), &dwNumBytesWritten, NULL);
  143. if (bRet)
  144. {
  145. SetEndOfFile(hFile);
  146. }
  147. }
  148. }
  149. else
  150. {
  151. bRet = (SetFilePointer (hFile, sizeof(DWORD)*dwOffset, 0, FILE_BEGIN) != INVALID_SET_FILE_POINTER) ;
  152. if (!bRet || !WriteFile(hFile, &dwValue, sizeof(DWORD), &dwNumBytesWritten, NULL) ||
  153. (dwNumBytesWritten != (sizeof(DWORD))))
  154. {
  155. //OK, this failed!!!
  156. CloseHandle(hFile);
  157. return FALSE;
  158. }
  159. }
  160. //Make sure it really is flushed to the disk
  161. FlushFileBuffers(hFile);
  162. CloseHandle(hFile);
  163. return bRet;
  164. }
  165. return FALSE;
  166. }
  167. TCHAR *CPersistentConfig::GetFullFilename(const TCHAR *pszFilename)
  168. {
  169. size_t bufferLength = lstrlen(m_Directory.GetStr()) + lstrlen(pszFilename) + 2;
  170. TCHAR *pszPathFilename = new TCHAR[bufferLength];
  171. if (pszPathFilename)
  172. {
  173. StringCchCopy(pszPathFilename, bufferLength, m_Directory.GetStr());
  174. if ((lstrlen(pszPathFilename)) && (pszPathFilename[lstrlen(pszPathFilename)-1] != __TEXT('\\')))
  175. {
  176. StringCchCat(pszPathFilename, bufferLength, __TEXT("\\"));
  177. }
  178. StringCchCat(pszPathFilename, bufferLength, pszFilename);
  179. }
  180. return pszPathFilename;
  181. }
  182. void CPersistentConfig::TidyUp()
  183. {
  184. //Recover the configuration file.
  185. //-------------------------------
  186. wmilib::auto_buffer<TCHAR> pszOriginalFile(GetFullFilename(WinMgmt_CFG_ACTUAL));
  187. wmilib::auto_buffer<TCHAR> pszPendingFile(GetFullFilename(WinMgmt_CFG_PENDING));
  188. wmilib::auto_buffer<TCHAR> pszBackupFile(GetFullFilename(WinMgmt_CFG_BACKUP));
  189. if (NULL == pszOriginalFile.get() ||
  190. NULL == pszPendingFile.get() ||
  191. NULL == pszBackupFile.get()) return;
  192. if (FileExists(pszOriginalFile.get()))
  193. {
  194. if (FileExists(pszPendingFile.get()))
  195. {
  196. if (FileExists(pszBackupFile.get()))
  197. {
  198. //BAD - Unexpected situation.
  199. DeleteFile(pszPendingFile.get());
  200. DeleteFile(pszBackupFile.get());
  201. //Back to the point where the interrupted operation did not
  202. //happen
  203. }
  204. else
  205. {
  206. //Pending file with original file means we cannot guarentee
  207. //the integrety of the pending file so the last operation
  208. //will be lost.
  209. DeleteFile(pszPendingFile.get());
  210. //Back to the point where the interrupted operation did not
  211. //happen
  212. }
  213. }
  214. else
  215. {
  216. if (FileExists(pszBackupFile.get()))
  217. {
  218. //Means we successfully copied the pending file to the original
  219. DeleteFile(pszBackupFile.get());
  220. //Everything is now normal. Interrupted Operation completed!
  221. }
  222. else
  223. {
  224. //Nothing out of the ordinary here.
  225. }
  226. }
  227. }
  228. else
  229. {
  230. if (FileExists(pszPendingFile.get()))
  231. {
  232. if (FileExists(pszBackupFile.get()))
  233. {
  234. //This is an expected behaviour at the point we have renamed
  235. //the original file to the backup file.
  236. MoveFile(pszPendingFile.get(), pszOriginalFile.get());
  237. DeleteFile(pszBackupFile.get());
  238. //Everything is now normal. Interrupted operation completed!
  239. }
  240. else
  241. {
  242. //BAD - Unexpected situation.
  243. DeleteFile(pszPendingFile.get());
  244. //There are now no files! Operation did not take place
  245. //and there are now no files left. This should be a
  246. //recoverable scenario!
  247. }
  248. }
  249. else
  250. {
  251. if (FileExists(pszBackupFile.get()))
  252. {
  253. //BAD - Unexpected situation.
  254. DeleteFile(pszBackupFile.get());
  255. //There are now no files! Operation did not take place
  256. //and there are now no files left. This should be a
  257. //recoverable scenario!
  258. }
  259. else
  260. {
  261. //May be BAD! There are no files! This should be a
  262. //recoverable scenario!
  263. }
  264. }
  265. }
  266. }
  267. //*****************************************************************************
  268. //
  269. // FileExists()
  270. //
  271. // Returns TRUE if the file exists, FALSE otherwise (or if an error
  272. // occurs while opening the file.
  273. //*****************************************************************************
  274. BOOL CPersistentConfig::FileExists(const TCHAR *pszFilename)
  275. {
  276. BOOL bExists = FALSE;
  277. HANDLE hFile = CreateFile(pszFilename, 0, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  278. if (hFile != INVALID_HANDLE_VALUE)
  279. {
  280. bExists = TRUE;
  281. CloseHandle(hFile);
  282. }
  283. else
  284. {
  285. //If the file does not exist we should have a LastError of ERROR_NOT_FOUND
  286. DWORD dwError = GetLastError();
  287. if (dwError != ERROR_FILE_NOT_FOUND)
  288. {
  289. // DEBUGTRACE((LOG_WBEMCORE,"File %s could not be opened for a reason other than not existing\n", pszFilename));
  290. }
  291. }
  292. return bExists;
  293. }