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.

426 lines
12 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. tcontrol.c
  5. Abstract:
  6. Test for cluster group controls
  7. Author:
  8. Rod Gamache (rodga) 30-Dec-1996
  9. Revision History:
  10. --*/
  11. #include "windows.h"
  12. #include "cluster.h"
  13. #include "stdio.h"
  14. #include "stdlib.h"
  15. #include "resapi.h"
  16. LPWSTR ClusterName=NULL;
  17. LPWSTR GroupName=NULL;
  18. LPWSTR NodeName=NULL;
  19. DWORD ControlCode=0xffffffff;
  20. DWORD Access=CLUS_ACCESS_READ;
  21. #if 1
  22. typedef struct _PROP_ITEM_16 {
  23. DWORD NameType;
  24. DWORD NameLength;
  25. WCHAR PI[16];
  26. } PROP_ITEM_16;
  27. typedef struct _PROP_ITEM_18 {
  28. DWORD NameType;
  29. DWORD NameLength;
  30. WCHAR PI[18];
  31. } PROP_ITEM_18;
  32. typedef struct _PROP_ITEM_20 {
  33. DWORD NameType;
  34. DWORD NameLength;
  35. WCHAR PI[20];
  36. } PROP_ITEM_20;
  37. typedef struct _PROP_ITEM_ALIGN_15 {
  38. DWORD NameType;
  39. DWORD NameLength;
  40. WCHAR PI[15];
  41. WCHAR _align;
  42. } PROP_ITEM_ALIGN_15;
  43. typedef struct _PROP_ITEM_ALIGN_17 {
  44. DWORD NameType;
  45. DWORD NameLength;
  46. WCHAR PI[17];
  47. WCHAR _align;
  48. } PROP_ITEM_ALIGN_17;
  49. typedef struct _PROP_DWORD_VALUE {
  50. DWORD ValueType;
  51. DWORD ValueLength;
  52. DWORD Value;
  53. DWORD align;
  54. } PROP_DWORD_VALUE;
  55. typedef struct _PROP_LIST {
  56. DWORD ItemCount;
  57. PROP_ITEM_16 PropItem1; // PersistentState (16 chars)
  58. PROP_DWORD_VALUE PropValue1;
  59. PROP_ITEM_18 PropItem2; // FailoverThreshold (18 chars)
  60. PROP_DWORD_VALUE PropValue2;
  61. PROP_ITEM_ALIGN_15 PropItem3; // FailoverPeriod (15 chars)
  62. PROP_DWORD_VALUE PropValue3;
  63. PROP_ITEM_ALIGN_17 PropItem4; // AutoFailbackType (17 chars)
  64. PROP_DWORD_VALUE PropValue4;
  65. PROP_ITEM_20 PropItem5; // FailbackWindowStart (20 chars)
  66. PROP_DWORD_VALUE PropValue5;
  67. PROP_ITEM_18 PropItem6; // FailbackWindowEnd (18 chars)
  68. PROP_DWORD_VALUE PropValue6;
  69. DWORD EndValue2;
  70. } PROP_LIST;
  71. #pragma warning( default : 4200 )
  72. #endif
  73. #if 1
  74. PROP_LIST PropList = {
  75. 0x00000006, // # of parameters
  76. 0x00040003,
  77. 0x00000020,
  78. L"PersistentState",
  79. 0x00010002,
  80. 0x00000004,
  81. 0x00000001, // State is on
  82. 0x00000000,
  83. 0x00040003, // Name
  84. 0x00000024, // Name Length
  85. L"FailoverThreshold",
  86. 0x00010002,
  87. 0x00000004,
  88. 0x0000000a, // Failover count is 10
  89. 0x00000000,
  90. 0x00040003, // Name
  91. 0x0000001e, // Name Length
  92. L"FailoverPeriod", // Not a multiple of 4 bytes
  93. 0x0, // alignment needed
  94. 0x00010002,
  95. 0x00000004,
  96. 0x00000006,
  97. 0x00000000,
  98. 0x00040003,
  99. 0x00000022,
  100. L"AutoFailbackType", // Not a multiple of 4 bytes
  101. 0x0, // alignment needed
  102. 0x00010002,
  103. 0x00000004,
  104. 0x00000000,
  105. 0x00000000,
  106. 0x00040003, // Name
  107. 0x00000028, // Name Length
  108. L"FailbackWindowStart",
  109. 0x00010002,
  110. 0x00000004,
  111. 0x2,
  112. 0x00000000,
  113. 0x00040003, // Name
  114. 0x00000024, // Name Length
  115. L"FailbackWindowEnd",
  116. 0x00010002,
  117. 0x00000004,
  118. 0x3,
  119. 0x00000000,
  120. 0x00000000 };
  121. #else
  122. DWORD PropList[] = {
  123. 0x00000006, 0x00040003, 0x00000020, 0x00650050,
  124. 0x00730072, 0x00730069, 0x00650074, 0x0074006e,
  125. 0x00740053, 0x00740061, 0x00000065, 0x00010002,
  126. 0x00000004, 0x00000001, 0x00000000, 0x00040003,
  127. 0x00000024, 0x00610046, 0x006c0069, 0x0076006f,
  128. 0x00720065, 0x00680054, 0x00650072, 0x00680073,
  129. 0x006c006f, 0x00000064, 0x00010002, 0x00000004,
  130. 0x0000000a, 0x00000000, 0x00040003, 0x0000001e,
  131. 0x00610046, 0x006c0069, 0x0076006f, 0x00720065,
  132. 0x00650050, 0x00690072, 0x0064006f, 0x00000000, // Alignment needed 4th dword
  133. 0x00010002, 0x00000004, 0x00000006, 0x00000000,
  134. 0x00040003, 0x00000022, 0x00750041, 0x006f0074,
  135. 0x00610046, 0x006c0069, 0x00610062, 0x006b0063,
  136. 0x00790054, 0x00650070, 0x00000000, 0x00010002, // Alignment needed 3rd dword
  137. 0x00000004, 0x00000000, 0x00000000, 0x00040003,
  138. 0x00000028, 0x00610046, 0x006c0069, 0x00610062,
  139. 0x006b0063, 0x00690057, 0x0064006e, 0x0077006f,
  140. 0x00740053, 0x00720061, 0x00000074, 0x00010002,
  141. 0x00000004, 0x2, 0x00000000, 0x00040003,
  142. 0x00000024, 0x00610046, 0x006c0069, 0x00610062,
  143. 0x006b0063, 0x00690057, 0x0064006e, 0x0077006f,
  144. 0x006e0045, 0x00000064, 0x00010002, 0x00000004,
  145. 0x3, 0x00000000, 0x00000000 };
  146. #endif
  147. CHAR UsageText[] =
  148. "TCONTROL [-c cluster] -n node -g group -a access ControlCode\n"
  149. " cluster\tspecifies the name of the cluster to connect to\n"
  150. " node\tspecifies the node to direct the request to\n"
  151. " group\tspecifies the name of the group to control\n"
  152. " access\tspecifies the access to the group (read, write or any)\n"
  153. " ControlCode\ta number between 1 and 99\n";
  154. void
  155. Usage(
  156. void
  157. )
  158. {
  159. fprintf(stderr, UsageText);
  160. exit(1);
  161. }
  162. LPWSTR
  163. GetString(
  164. IN LPSTR String
  165. )
  166. {
  167. LPWSTR wString;
  168. DWORD Length;
  169. Length = strlen(String)+1;
  170. wString = malloc(Length*sizeof(WCHAR));
  171. if (wString == NULL) {
  172. fprintf(stderr, "GetString couldn't malloc %d bytes\n",Length*sizeof(WCHAR));
  173. }
  174. mbstowcs(wString, String, Length);
  175. return(wString);
  176. }
  177. void
  178. ParseArgs(
  179. int argc,
  180. char *argv[]
  181. )
  182. {
  183. int i;
  184. DWORD IntCount;
  185. DWORD Value;
  186. CHAR TestValue[16];
  187. PUCHAR ControlData;
  188. LPWSTR access;
  189. for (i=1;i<argc;i++) {
  190. if ((argv[i][0] == '-') ||
  191. (argv[i][0] == '/')) {
  192. switch (argv[i][1]) {
  193. case 'c':
  194. if (++i == argc) {
  195. Usage();
  196. }
  197. ClusterName = GetString(argv[i]);
  198. break;
  199. case 'n':
  200. if ( ++i == argc ) {
  201. Usage();
  202. }
  203. NodeName = GetString(argv[i]);
  204. break;
  205. case 'g':
  206. if ( ++i == argc ) {
  207. Usage();
  208. }
  209. GroupName = GetString(argv[i]);
  210. fprintf(stdout, "Group = %ws\n", GroupName);
  211. break;
  212. case 'a':
  213. if ( ++i == argc ) {
  214. Usage();
  215. }
  216. access = GetString(argv[i]);
  217. if ( lstrcmpiW( access, L"read" ) ) {
  218. Access = CLUS_ACCESS_READ;
  219. } else if ( lstrcmpiW( access, L"write" ) ) {
  220. Access = CLUS_ACCESS_WRITE;
  221. } else if ( lstrcmpiW( access, L"any" ) ) {
  222. Access = CLUS_ACCESS_ANY;
  223. } else {
  224. Usage();
  225. }
  226. break;
  227. default:
  228. Usage();
  229. break;
  230. }
  231. } else {
  232. ControlData = argv[i];
  233. IntCount = sscanf( ControlData, "%d", &Value );
  234. if ( IntCount == 1 ) {
  235. sprintf( TestValue, "%d\0", Value );
  236. if ( strcmp( TestValue, ControlData ) == 0 ) {
  237. ControlCode = Value;
  238. fprintf(stdout, "ControlCode = %d\n", ControlCode);
  239. }
  240. }
  241. }
  242. }
  243. if ( ControlCode == 0xffffffff ) {
  244. Usage();
  245. }
  246. }
  247. _cdecl
  248. main (argc, argv)
  249. int argc;
  250. char *argv[];
  251. {
  252. HCLUSTER hClus;
  253. HGROUP hGroup;
  254. HNODE hNode = NULL;
  255. DWORD status;
  256. DWORD ReturnSize;
  257. DWORD bufSize;
  258. CHAR InBuffer[64];
  259. DWORD i,j;
  260. LPDWORD Data;
  261. LPDWORD PrintData;
  262. CHAR PrintBuffer[32];
  263. PUCHAR buffer;
  264. DWORD controlCode;
  265. BOOL retry = TRUE;
  266. DWORD inputSize;
  267. ParseArgs(argc, argv);
  268. hClus = OpenCluster(ClusterName);
  269. if (hClus == NULL) {
  270. fprintf(stderr,
  271. "OpenCluster %ws failed %d\n",
  272. (ClusterName == NULL) ? L"(NULL)" : ClusterName,
  273. GetLastError());
  274. return(0);
  275. }
  276. hGroup = OpenClusterGroup( hClus, GroupName );
  277. if ( hGroup == NULL ) {
  278. fprintf(stderr,
  279. "OpenGroup %ws failed %d\n", GroupName, GetLastError());
  280. return(0);
  281. }
  282. if ( NodeName != NULL ) {
  283. hNode = OpenClusterNode( hClus, NodeName );
  284. if ( hNode == NULL ) {
  285. fprintf(stderr,
  286. "OpenNode %ws failed %d\n", NodeName, GetLastError());
  287. return(0);
  288. }
  289. }
  290. if ( Access == CLUS_ACCESS_WRITE ) {
  291. controlCode = CLCTL_EXTERNAL_CODE( ControlCode, Access, CLUS_MODIFY );
  292. } else {
  293. controlCode = CLCTL_EXTERNAL_CODE( ControlCode, Access, CLUS_NO_MODIFY );
  294. }
  295. try_again:
  296. controlCode = CLUSCTL_GROUP_CODE( controlCode );
  297. ReturnSize = 0;
  298. status = ClusterGroupControl( hGroup,
  299. hNode,
  300. controlCode,
  301. NULL,
  302. 0,
  303. NULL,
  304. 0,
  305. &ReturnSize );
  306. if ( retry &&
  307. (status == ERROR_INVALID_FUNCTION) ) {
  308. controlCode = CLCTL_EXTERNAL_CODE( ControlCode, CLUS_ACCESS_WRITE, CLUS_MODIFY );
  309. retry = FALSE;
  310. goto try_again;
  311. }
  312. fprintf(stdout, "Status of initial request is %d, size is %d.\n",
  313. status, ReturnSize);
  314. if ( (status != ERROR_SUCCESS) ||
  315. (ReturnSize == 0) ) {
  316. return(0);
  317. }
  318. bufSize = ReturnSize;
  319. buffer = LocalAlloc( LMEM_FIXED, bufSize );
  320. if ( buffer == NULL ) {
  321. fprintf(stdout, "Failed to allocate a return buffer.\n");
  322. return(0);
  323. }
  324. status = ClusterGroupControl( hGroup,
  325. hNode,
  326. controlCode,
  327. NULL,
  328. 0,
  329. buffer,
  330. bufSize,
  331. &ReturnSize );
  332. fprintf(stdout, "Status of Control request = %d, size = %d\n",
  333. status, ReturnSize);
  334. if ( status == ERROR_SUCCESS ) {
  335. inputSize = ReturnSize;
  336. Data = (LPDWORD)buffer;
  337. PrintData = (LPDWORD)PrintBuffer;
  338. while ( ReturnSize ) {
  339. j = ReturnSize;
  340. if ( j > 16 ) j = 16;
  341. ZeroMemory(PrintBuffer, 18);
  342. MoveMemory(PrintBuffer, Data, j);
  343. ReturnSize -= j;
  344. for ( i = 0; i < 4; i++ ) {
  345. fprintf(stdout,
  346. " %08lx", PrintData[i]);
  347. }
  348. fprintf(stdout, " ");
  349. for ( i = 0; i < 16; i++ ) {
  350. fprintf(stdout, "%c",
  351. isprint(PrintBuffer[i])?PrintBuffer[i]:'.');
  352. }
  353. Data += 4;
  354. fprintf(stdout, "\n");
  355. }
  356. switch ( controlCode ) {
  357. case CLUSCTL_GROUP_GET_COMMON_PROPERTIES:
  358. controlCode = CLUSCTL_GROUP_SET_COMMON_PROPERTIES;
  359. break;
  360. case CLUSCTL_GROUP_GET_PRIVATE_PROPERTIES:
  361. controlCode = CLUSCTL_GROUP_SET_PRIVATE_PROPERTIES;
  362. break;
  363. default:
  364. controlCode = 0;
  365. break;
  366. }
  367. if ( controlCode != 0 ) {
  368. status = ClusterGroupControl( hGroup,
  369. hNode,
  370. controlCode,
  371. &PropList,
  372. sizeof(PropList),
  373. NULL,
  374. 0,
  375. &ReturnSize );
  376. }
  377. fprintf(stdout, "Status of *INPUT* Control request = %d, insize = %d, retsize = %d\n",
  378. status, sizeof(PropList), ReturnSize);
  379. }
  380. LocalFree(buffer);
  381. return(0);
  382. }