Windows NT 4.0 source code leak
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.

497 lines
14 KiB

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