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.

505 lines
14 KiB

  1. //
  2. // Foreign computer support needs more work (a-robw)
  3. //
  4. #ifdef FOREIGN_COMPUTER_SUPPORT
  5. #undef FOREIGN_COMPUTER_SUPPORT
  6. #endif
  7. #include "setedit.h"
  8. #include "system.h" // external declarations for this file
  9. #include "perfdata.h"
  10. #include "perfmops.h"
  11. #include "pmemory.h"
  12. #include "utils.h" // for strsame, et al
  13. #include "sizes.h"
  14. DWORD
  15. SystemCount(
  16. PPERFSYSTEM pSystemFirst
  17. )
  18. {
  19. PPERFSYSTEM pSystem ;
  20. DWORD iNumSystems ;
  21. iNumSystems = 0 ;
  22. for (pSystem = pSystemFirst ;
  23. pSystem ;
  24. pSystem = pSystem->pSystemNext) {
  25. iNumSystems++ ;
  26. }
  27. return iNumSystems ;
  28. }
  29. BOOL
  30. SystemSetupThread (
  31. PPERFSYSTEM pSystem
  32. )
  33. {
  34. DWORD dwThreadID ;
  35. HANDLE hThread ;
  36. HANDLE hStateDataMutex ;
  37. HANDLE hPerfDataEvent ;
  38. SECURITY_ATTRIBUTES SecAttr ;
  39. PPERFDATA pSystemPerfData ;
  40. SecAttr.nLength = sizeof (SecAttr) ;
  41. SecAttr.bInheritHandle = TRUE ;
  42. SecAttr.lpSecurityDescriptor = NULL ;
  43. hThread = CreateThread (&SecAttr, 1024L,
  44. (LPTHREAD_START_ROUTINE)PerfDataThread, (LPVOID)(pSystem), 0L, &dwThreadID);
  45. if (!hThread) {
  46. SystemFree (pSystem, TRUE);
  47. return (FALSE) ;
  48. }
  49. // create a State Data Lock mutex
  50. hStateDataMutex = CreateMutex (&SecAttr, FALSE, NULL);
  51. if (!hStateDataMutex) {
  52. CloseHandle (hThread) ;
  53. SystemFree (pSystem, TRUE);
  54. return (FALSE);
  55. }
  56. hPerfDataEvent = CreateEvent (&SecAttr, TRUE, 0L, NULL) ;
  57. if (!hPerfDataEvent) {
  58. CloseHandle (hStateDataMutex) ;
  59. CloseHandle (hThread) ;
  60. SystemFree (pSystem, TRUE);
  61. return (FALSE);
  62. }
  63. // allocate Perfdata
  64. pSystemPerfData = (PPERFDATA) MemoryAllocate (4096L) ;
  65. if (!pSystemPerfData) {
  66. CloseHandle (hPerfDataEvent) ;
  67. CloseHandle (hStateDataMutex) ;
  68. CloseHandle (hThread) ;
  69. SystemFree (pSystem, TRUE);
  70. return (FALSE);
  71. }
  72. // now setup the pSystem..
  73. pSystem->dwThreadID = dwThreadID ;
  74. pSystem->hThread = hThread ;
  75. pSystem->hPerfDataEvent = hPerfDataEvent ;
  76. pSystem->pSystemPerfData = pSystemPerfData ;
  77. pSystem->hStateDataMutex = hStateDataMutex ;
  78. return (TRUE) ;
  79. }
  80. PPERFSYSTEM
  81. SystemCreate (
  82. LPCTSTR lpszSystemName
  83. )
  84. {
  85. PPERFSYSTEM pSystem ;
  86. PPERFDATA pLocalPerfData;
  87. DWORD Status ;
  88. SIZE_T dwMemSize;
  89. TCHAR GlobalValueBuffer[] = L"Global" ;
  90. TCHAR ForeignValueBuffer[8+MAX_SYSTEM_NAME_LENGTH+1] =
  91. L"Foreign " ;
  92. // attempt to allocate system data structure
  93. pSystem = MemoryAllocate (sizeof (PERFSYSTEM)) ;
  94. if (!pSystem) {
  95. SetLastError (ERROR_OUTOFMEMORY);
  96. return (NULL) ;
  97. }
  98. // initialize name and help table pointers
  99. pSystem->CounterInfo.pNextTable = NULL;
  100. pSystem->CounterInfo.dwLangId = 0;
  101. pSystem->CounterInfo.dwLastId = 0;
  102. pSystem->CounterInfo.TextString = NULL;
  103. lstrcpy (pSystem->sysName, lpszSystemName) ;
  104. // try to open key to registry, error code is in GetLastError()
  105. pSystem->sysDataKey = OpenSystemPerfData(lpszSystemName);
  106. // if a Null Key was returned then:
  107. // a) there's no such computer
  108. // b) the system is a foreign computer
  109. //
  110. // before giving up, then see if it's a foreign computer
  111. if (!pSystem->sysDataKey) {
  112. // build foreign computer string
  113. lstrcat(ForeignValueBuffer, lpszSystemName) ;
  114. // assign System value name pointer to the local variable for trial
  115. pSystem->lpszValue = ForeignValueBuffer;
  116. // try to get data from the computer to see if it's for real
  117. // otherwise, give up and return NULL
  118. pLocalPerfData = MemoryAllocate (STARTING_SYSINFO_SIZE);
  119. if (pLocalPerfData == NULL) {
  120. SystemFree (pSystem, TRUE);
  121. SetLastError (ERROR_OUTOFMEMORY);
  122. return (NULL);
  123. } else {
  124. pSystem->sysDataKey = HKEY_PERFORMANCE_DATA; // local machine
  125. bCloseLocalMachine = TRUE ;
  126. dwMemSize = STARTING_SYSINFO_SIZE;
  127. Status = GetSystemPerfData (
  128. pSystem->sysDataKey,
  129. pSystem->lpszValue,
  130. pLocalPerfData,
  131. &dwMemSize);
  132. // success means a valid buffer came back
  133. // more data means someone tried (so it's probably good (?)
  134. if (!((Status == ERROR_MORE_DATA) || (Status == ERROR_SUCCESS)) ||
  135. !((pLocalPerfData->Signature[0] == (WCHAR)'P') &&
  136. (pLocalPerfData->Signature[1] == (WCHAR)'E') &&
  137. (pLocalPerfData->Signature[2] == (WCHAR)'R') &&
  138. (pLocalPerfData->Signature[3] == (WCHAR)'F'))) {
  139. SetLastError (ERROR_BAD_NET_NAME); // unable to find name
  140. SystemFree (pSystem, TRUE);
  141. MemoryFree (pLocalPerfData); // don't really need anything from it
  142. return NULL;
  143. }
  144. MemoryFree (pLocalPerfData); // don't really need anything from it
  145. // ok, so we've established that a foreign data provider
  146. // exists, now to finish the initialization.
  147. // change system name in structure to get counter names
  148. lstrcpy (pSystem->sysName, LocalComputerName);
  149. Status = GetSystemNames(pSystem); // get counter names & explain text
  150. if (Status != ERROR_SUCCESS) {
  151. // unable to get names so bail out
  152. SystemFree (pSystem, TRUE);
  153. SetLastError (Status);
  154. return (NULL) ;
  155. }
  156. // restore computer name for displays, etc.
  157. lstrcpy (pSystem->sysName, lpszSystemName);
  158. // allocate value string buffer
  159. pSystem->lpszValue = MemoryAllocate (TEMP_BUF_LEN*sizeof(WCHAR));
  160. if (!pSystem->lpszValue) {
  161. // unable to allocate memory
  162. SystemFree (pSystem, TRUE);
  163. SetLastError (ERROR_OUTOFMEMORY);
  164. return (NULL) ;
  165. } else {
  166. lstrcpy (pSystem->lpszValue, ForeignValueBuffer);
  167. }
  168. }
  169. } else {
  170. // if here, then a connection to the system's registry was established
  171. // so continue with the system data structure initialization
  172. // get counter names & explain text from local computer
  173. Status = GetSystemNames(pSystem);
  174. if (Status != ERROR_SUCCESS) {
  175. // unable to get names so bail out
  176. SystemFree (pSystem, TRUE);
  177. SetLastError (Status);
  178. return (NULL) ;
  179. }
  180. // allocate value string buffer
  181. pSystem->lpszValue = MemoryAllocate(TEMP_BUF_LEN*sizeof(WCHAR));
  182. if (!pSystem->lpszValue) {
  183. // unable to allocate memory
  184. SystemFree (pSystem, TRUE);
  185. SetLastError (ERROR_OUTOFMEMORY);
  186. return (NULL) ;
  187. } else {
  188. SetSystemValueNameToGlobal (pSystem);
  189. }
  190. }
  191. // initialize remaining system pointers
  192. pSystem->pSystemNext = NULL ;
  193. pSystem->FailureTime = 0;
  194. SetLastError (ERROR_SUCCESS);
  195. return (pSystem) ;
  196. }
  197. PPERFSYSTEM
  198. SystemGet (
  199. PPERFSYSTEM pSystemFirst,
  200. LPCTSTR lpszSystemName
  201. )
  202. {
  203. PPERFSYSTEM pSystem ;
  204. if (!pSystemFirst) {
  205. return (NULL) ;
  206. }
  207. for (pSystem = pSystemFirst ;
  208. pSystem ;
  209. pSystem = pSystem->pSystemNext) {
  210. if (strsamei (pSystem->sysName, lpszSystemName)) {
  211. return (pSystem) ;
  212. }
  213. }
  214. return (NULL) ;
  215. }
  216. PPERFSYSTEM
  217. SystemAdd (
  218. PPPERFSYSTEM ppSystemFirst,
  219. LPCTSTR lpszSystemName,
  220. HWND hDlg
  221. )
  222. {
  223. PPERFSYSTEM pSystem ;
  224. PPERFSYSTEM pSystemPrev ;
  225. TCHAR szMessage[256];
  226. DWORD dwLastError;
  227. if (!*ppSystemFirst) {
  228. *ppSystemFirst = SystemCreate (lpszSystemName) ;
  229. dwLastError = GetLastError();
  230. // save return value
  231. return (*ppSystemFirst) ;
  232. } else {
  233. for (pSystem = *ppSystemFirst ;
  234. pSystem ;
  235. pSystem = pSystem->pSystemNext) {
  236. pSystemPrev = pSystem ;
  237. if (strsamei (pSystem->sysName, lpszSystemName)) {
  238. return (pSystem) ;
  239. }
  240. }
  241. }
  242. // display message box here if an error occured trying to add
  243. // this system
  244. if (pSystem == NULL) {
  245. dwLastError = GetLastError();
  246. if (dwLastError == ERROR_ACCESS_DENIED) {
  247. DlgErrorBox (hDlg, ERR_ACCESS_DENIED);
  248. SetLastError (dwLastError); // to propogate up to caller
  249. }
  250. }
  251. return (pSystem);
  252. }
  253. void
  254. SystemFree (
  255. PPERFSYSTEM pSystem,
  256. BOOL bDeleteTheSystem
  257. )
  258. {
  259. PCOUNTERTEXT pCounter, pNextCounter;
  260. if (!pSystem) {
  261. // can't proceed
  262. return ;
  263. }
  264. if (pSystem->sysDataKey && pSystem->sysDataKey != HKEY_PERFORMANCE_DATA) {
  265. // close the remote computer key
  266. RegCloseKey (pSystem->sysDataKey);
  267. pSystem->sysDataKey = 0 ;
  268. }
  269. for (pCounter = pSystem->CounterInfo.pNextTable, pNextCounter = NULL;
  270. pCounter;
  271. pCounter = pNextCounter) {
  272. pNextCounter = pCounter->pNextTable;
  273. MemoryFree (pCounter);
  274. }
  275. pSystem->CounterInfo.pNextTable = NULL ;
  276. if (pSystem->CounterInfo.TextString) {
  277. MemoryFree (pSystem->CounterInfo.TextString);
  278. pSystem->CounterInfo.TextString = NULL ;
  279. }
  280. if (pSystem->CounterInfo.HelpTextString) {
  281. MemoryFree (pSystem->CounterInfo.HelpTextString);
  282. pSystem->CounterInfo.HelpTextString = NULL ;
  283. }
  284. pSystem->CounterInfo.dwLastId = 0 ;
  285. pSystem->CounterInfo.dwHelpSize = 0 ;
  286. pSystem->CounterInfo.dwCounterSize = 0 ;
  287. if (bDeleteTheSystem) {
  288. if (pSystem->lpszValue) {
  289. MemoryFree (pSystem->lpszValue);
  290. pSystem->lpszValue = NULL ;
  291. }
  292. MemoryFree (pSystem) ;
  293. }
  294. }
  295. void
  296. DeleteUnusedSystems (
  297. PPPERFSYSTEM ppSystemFirst ,
  298. int iNoUseSystems
  299. )
  300. {
  301. PPERFSYSTEM pPrevSys, pCurrentSys, pNextSys ;
  302. // delete all the marked system from the list header until
  303. // we hit one that is not marked
  304. while ((*ppSystemFirst)->bSystemNoLongerNeeded) {
  305. // delect from the list header
  306. pCurrentSys = *ppSystemFirst ;
  307. *ppSystemFirst = pCurrentSys->pSystemNext ;
  308. SystemFree (pCurrentSys, TRUE) ;
  309. iNoUseSystems-- ;
  310. if (iNoUseSystems <= 0 || !(*ppSystemFirst)) {
  311. // done
  312. break ;
  313. }
  314. }
  315. if (iNoUseSystems <= 0 || !(*ppSystemFirst)) {
  316. return ;
  317. }
  318. // now walk the list and delete each marked system
  319. for (pPrevSys = *ppSystemFirst, pCurrentSys = pPrevSys->pSystemNext ;
  320. pCurrentSys && iNoUseSystems > 0 ;
  321. pCurrentSys = pNextSys, iNoUseSystems--) {
  322. if (pCurrentSys->bSystemNoLongerNeeded) {
  323. // the current system is marked, updated the list and free
  324. // this system. No need to change pPrevSys here
  325. pNextSys = pPrevSys->pSystemNext = pCurrentSys->pSystemNext ;
  326. SystemFree (pCurrentSys, TRUE) ;
  327. } else {
  328. // pCurrentSys is OK, update the 2 list pointers and
  329. // carry on looping
  330. pPrevSys = pCurrentSys ;
  331. pNextSys = pCurrentSys->pSystemNext ;
  332. }
  333. }
  334. }
  335. void
  336. FreeSystems (
  337. PPERFSYSTEM pSystemFirst
  338. )
  339. {
  340. PPERFSYSTEM pSystem, pSystemNext ;
  341. for (pSystem = pSystemFirst;
  342. pSystem;
  343. pSystem = pSystemNext) {
  344. pSystemNext = pSystem->pSystemNext ;
  345. SystemFree (pSystem, TRUE) ;
  346. }
  347. }
  348. PPERFSYSTEM
  349. GetComputer (
  350. HDLG hDlg,
  351. WORD wControlID,
  352. BOOL bWarn,
  353. PPERFDATA *ppPerfData,
  354. PPERFSYSTEM *ppSystemFirst
  355. )
  356. /*
  357. Effect: Attempt to set the current computer to the one in the
  358. hWndComputers dialog edit box. If this computer system
  359. can be found, load the objects, etc. for the computer
  360. and set pSystem and ppPerfdata to the values for this
  361. system.
  362. */
  363. {
  364. TCHAR szComputer [MAX_SYSTEM_NAME_LENGTH + 1] ;
  365. PPERFSYSTEM pSystem;
  366. TCHAR tempBuffer [LongTextLen] ;
  367. DWORD dwBufferSize ;
  368. LPTSTR pBuffer = NULL ;
  369. DialogText (hDlg, wControlID, szComputer) ;
  370. // If necessary, add the system to the lists for this view.
  371. pSystem = SystemGet (*ppSystemFirst, szComputer) ;
  372. if (!pSystem) {
  373. pSystem = SystemAdd (ppSystemFirst, szComputer, hDlg) ;
  374. }
  375. if (!pSystem && bWarn) {
  376. DialogSetString (hDlg, wControlID, LocalComputerName) ;
  377. // Note: this will succeed since the local computer is always
  378. // available
  379. EditSetModified (GetDlgItem(hDlg, wControlID), FALSE) ;
  380. pSystem = SystemGet (*ppSystemFirst, LocalComputerName) ;
  381. if (!pSystem) {
  382. pSystem = SystemAdd (ppSystemFirst, LocalComputerName, hDlg) ;
  383. }
  384. // MessageBoxResource (hDlg, IDS_COMPUTERNOTFOUND, IDS_APPNAME, MB_OK) ;
  385. DlgErrorBox (hDlg, ERR_COMPUTERNOTFOUND) ;
  386. SetFocus (DialogControl(hDlg, wControlID)) ;
  387. }
  388. if (pSystem) {
  389. if (pSystem->lpszValue) {
  390. // save the previous lpszValue string before
  391. // SetSystemValueNameToGlobal mess it up
  392. dwBufferSize = (DWORD)MemorySize (pSystem->lpszValue) ;
  393. if (dwBufferSize <= sizeof(tempBuffer)) {
  394. pBuffer = tempBuffer ;
  395. } else {
  396. pBuffer = MemoryAllocate (dwBufferSize) ;
  397. }
  398. memcpy (pBuffer, pSystem->lpszValue, dwBufferSize) ;
  399. }
  400. SetSystemValueNameToGlobal (pSystem);
  401. UpdateSystemData (pSystem, ppPerfData) ;
  402. if (pSystem->lpszValue) {
  403. // retore the previous lpszValue string
  404. memcpy (pSystem->lpszValue, pBuffer, dwBufferSize) ;
  405. if (pBuffer != tempBuffer) {
  406. MemoryFree (pBuffer) ;
  407. }
  408. }
  409. }
  410. return (pSystem) ;
  411. }