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.

2722 lines
99 KiB

  1. /*--
  2. Copyright (c) 1987-1993 Microsoft Corporation
  3. Module Name:
  4. aztest.c
  5. Abstract:
  6. Test program for the azroles DLL.
  7. Author:
  8. Cliff Van Dyke (cliffv) 16-Apr-2001
  9. Environment:
  10. User mode only.
  11. Contains NT-specific code.
  12. Requires ANSI C extensions: slash-slash comments, long external names.
  13. Revision History:
  14. --*/
  15. //
  16. // Common include files.
  17. //
  18. #define UNICODE 1
  19. // #define SECURITY_WIN32 1
  20. #include <nt.h>
  21. #include <ntrtl.h>
  22. #include <nturtl.h>
  23. #include <windows.h>
  24. #include "azrolesp.h"
  25. #include <lmcons.h>
  26. #include <lmerr.h>
  27. #include <stdio.h> // printf
  28. #include <sddl.h>
  29. #include <ntstatus.dbg>
  30. #include <winerror.dbg>
  31. //
  32. // Sundry defines to enable optional tests
  33. //
  34. // #define ENABLE_LEAK 1 // Run a test that leaks memory
  35. // #define ENABLE_CAUGHT_AVS 1 // Run a test that AVs in azroles.dll (but the AV is caught)
  36. //
  37. // Structure to define an operation to preform
  38. //
  39. typedef struct _OPERATION {
  40. // The operation
  41. ULONG Opcode;
  42. // These are generic opcodes that work for all object types
  43. #define AzoGenCreate 0
  44. #define AzoGenOpen 1
  45. #define AzoGenEnum 2
  46. #define AzoGenGetProp 3
  47. #define AzoGenSetProp 4
  48. #define AzoGenAddProp 5
  49. #define AzoGenRemProp 6
  50. #define AzoGenDelete 7
  51. #define AzoGenMax 50
  52. //
  53. // These are object specific opcodes
  54. //
  55. #define AzoApp 100
  56. #define AzoAppCreate (AzoApp+AzoGenCreate)
  57. #define AzoAppOpen (AzoApp+AzoGenOpen)
  58. #define AzoAppEnum (AzoApp+AzoGenEnum)
  59. #define AzoAppGetProp (AzoApp+AzoGenGetProp)
  60. #define AzoAppSetProp (AzoApp+AzoGenSetProp)
  61. #define AzoAppDelete (AzoApp+AzoGenDelete)
  62. #define AzoOp 200
  63. #define AzoOpCreate (AzoOp+AzoGenCreate)
  64. #define AzoOpOpen (AzoOp+AzoGenOpen)
  65. #define AzoOpEnum (AzoOp+AzoGenEnum)
  66. #define AzoOpGetProp (AzoOp+AzoGenGetProp)
  67. #define AzoOpSetProp (AzoOp+AzoGenSetProp)
  68. #define AzoOpDelete (AzoOp+AzoGenDelete)
  69. #define AzoTask 300
  70. #define AzoTaskCreate (AzoTask+AzoGenCreate)
  71. #define AzoTaskOpen (AzoTask+AzoGenOpen)
  72. #define AzoTaskEnum (AzoTask+AzoGenEnum)
  73. #define AzoTaskGetProp (AzoTask+AzoGenGetProp)
  74. #define AzoTaskSetProp (AzoTask+AzoGenSetProp)
  75. #define AzoTaskAddProp (AzoTask+AzoGenAddProp)
  76. #define AzoTaskRemProp (AzoTask+AzoGenRemProp)
  77. #define AzoTaskDelete (AzoTask+AzoGenDelete)
  78. #define AzoScope 400
  79. #define AzoScopeCreate (AzoScope+AzoGenCreate)
  80. #define AzoScopeOpen (AzoScope+AzoGenOpen)
  81. #define AzoScopeEnum (AzoScope+AzoGenEnum)
  82. #define AzoScopeGetProp (AzoScope+AzoGenGetProp)
  83. #define AzoScopeSetProp (AzoScope+AzoGenSetProp)
  84. #define AzoScopeDelete (AzoScope+AzoGenDelete)
  85. #define AzoGroup 500
  86. #define AzoGroupCreate (AzoGroup+AzoGenCreate)
  87. #define AzoGroupOpen (AzoGroup+AzoGenOpen)
  88. #define AzoGroupEnum (AzoGroup+AzoGenEnum)
  89. #define AzoGroupGetProp (AzoGroup+AzoGenGetProp)
  90. #define AzoGroupSetProp (AzoGroup+AzoGenSetProp)
  91. #define AzoGroupAddProp (AzoGroup+AzoGenAddProp)
  92. #define AzoGroupRemProp (AzoGroup+AzoGenRemProp)
  93. #define AzoGroupDelete (AzoGroup+AzoGenDelete)
  94. #define AzoRole 600
  95. #define AzoRoleCreate (AzoRole+AzoGenCreate)
  96. #define AzoRoleOpen (AzoRole+AzoGenOpen)
  97. #define AzoRoleEnum (AzoRole+AzoGenEnum)
  98. #define AzoRoleGetProp (AzoRole+AzoGenGetProp)
  99. #define AzoRoleSetProp (AzoRole+AzoGenSetProp)
  100. #define AzoRoleAddProp (AzoRole+AzoGenAddProp)
  101. #define AzoRoleRemProp (AzoRole+AzoGenRemProp)
  102. #define AzoRoleDelete (AzoRole+AzoGenDelete)
  103. #define AzoJP 700
  104. #define AzoJPCreate (AzoJP+AzoGenCreate)
  105. #define AzoJPOpen (AzoJP+AzoGenOpen)
  106. #define AzoJPEnum (AzoJP+AzoGenEnum)
  107. #define AzoJPGetProp (AzoJP+AzoGenGetProp)
  108. #define AzoJPSetProp (AzoJP+AzoGenSetProp)
  109. #define AzoJPDelete (AzoJP+AzoGenDelete)
  110. //
  111. // Real APIs that don't map to the generic APIs
  112. #define AzoInit 1000
  113. #define AzoClose 1001
  114. //
  115. // Pseudo opcode for TestLink subroutine
  116. //
  117. #define AzoTl 2000
  118. #define AzoTlCreate (AzoTl+AzoGenCreate)
  119. #define AzoTlOpen (AzoTl+AzoGenOpen)
  120. #define AzoTlEnum (AzoTl+AzoGenEnum)
  121. #define AzoTlGetProp (AzoTl+AzoGenGetProp)
  122. #define AzoTlSetProp (AzoTl+AzoGenSetProp)
  123. #define AzoTlDelete (AzoTl+AzoGenDelete)
  124. #define AzoTlMax 2999
  125. // Opcodes that aren't really API calls
  126. #define AzoTestLink 0xFFFFFFFB
  127. #define AzoGoSub 0xFFFFFFFC
  128. #define AzoEcho 0xFFFFFFFD
  129. #define AzoDupHandle 0xFFFFFFFE
  130. #define AzoEndOfList 0xFFFFFFFF
  131. // Input Handle
  132. PAZ_HANDLE InputHandle;
  133. // Input Parameter
  134. LPWSTR Parameter1;
  135. // Output Handle
  136. PAZ_HANDLE OutputHandle;
  137. // Expected result status code
  138. ULONG ExpectedStatus;
  139. // List of operations to perform on each enumeration handle
  140. struct _OPERATION *EnumOperations;
  141. // Expected result String parameter
  142. LPWSTR ExpectedParameter1;
  143. // Property ID of Get/SetPropertyId functions
  144. ULONG PropertyId;
  145. } OPERATION, *POPERATION;
  146. //
  147. // Global handles
  148. //
  149. AZ_HANDLE AdminMgrHandle1;
  150. AZ_HANDLE AdminMgrHandle2;
  151. AZ_HANDLE AppHandle1;
  152. AZ_HANDLE AppHandle2;
  153. AZ_HANDLE OpHandle1;
  154. AZ_HANDLE TaskHandle1;
  155. AZ_HANDLE ScopeHandle1;
  156. AZ_HANDLE GroupHandleA;
  157. AZ_HANDLE GroupHandle1;
  158. AZ_HANDLE RoleHandleA;
  159. AZ_HANDLE JPHandle1;
  160. AZ_HANDLE JPHandleA;
  161. AZ_HANDLE JPHandleB;
  162. AZ_HANDLE GenParentHandle1;
  163. AZ_HANDLE GenHandle1;
  164. AZ_HANDLE GenHandle2;
  165. AZ_HANDLE GenHandleE;
  166. AZ_HANDLE GenHandleE2;
  167. //
  168. // Constant property values
  169. //
  170. ULONG Zero = 0;
  171. ULONG Eight = 8;
  172. ULONG GtMem = AZ_GROUPTYPE_MEMBERSHIP;
  173. ULONG GtLdap = AZ_GROUPTYPE_LDAP_QUERY;
  174. //
  175. // Generic operations valid for all enumerations
  176. //
  177. // Requires GenHandleE to already be set
  178. //
  179. // Test double close of enum handle
  180. OPERATION OpAppChildGenEnum1[] = {
  181. { AzoDupHandle, &GenHandleE, NULL, &GenHandleE2, NO_ERROR },
  182. { AzoClose, &GenHandleE, NULL, NULL, NO_ERROR },
  183. { AzoClose, &GenHandleE, NULL, NULL, ERROR_INVALID_HANDLE },
  184. { AzoClose, &GenHandleE2, NULL, NULL, ERROR_INVALID_HANDLE },
  185. { AzoEndOfList }
  186. };
  187. // General purpose object enum
  188. OPERATION OpAppChildGenEnum2[] = {
  189. { AzoGenGetProp, &GenHandleE, NULL, NULL, NO_ERROR, NULL, NULL, AZ_PROP_NAME },
  190. { AzoGenGetProp, &GenHandleE, NULL, NULL, NO_ERROR, NULL, NULL, AZ_PROP_DESCRIPTION },
  191. { AzoClose, &GenHandleE, NULL, NULL, NO_ERROR },
  192. { AzoEndOfList }
  193. };
  194. //
  195. // Generic operations that work on *ALL* objects
  196. //
  197. // Requires GenParentHandle1 to already be set
  198. //
  199. OPERATION OpGen[] = {
  200. { AzoEcho, NULL, L"Gen object test" },
  201. { AzoGenCreate, &GenParentHandle1,L"Name1", &GenHandle1, NO_ERROR },
  202. { AzoClose, &GenHandle1, NULL, NULL, NO_ERROR },
  203. { AzoGenEnum, &GenHandle1, NULL, &GenHandleE, ERROR_INVALID_HANDLE },
  204. { AzoGenEnum, &GenParentHandle1,NULL, &GenHandleE, NO_ERROR, OpAppChildGenEnum1 },
  205. { AzoGenEnum, &GenParentHandle1,NULL, &GenHandleE, NO_ERROR, OpAppChildGenEnum2 },
  206. { AzoGenCreate, &GenParentHandle1,L"Name2", &GenHandle2, NO_ERROR },
  207. { AzoGenEnum, &GenParentHandle1,NULL, &GenHandleE, NO_ERROR, OpAppChildGenEnum2 },
  208. { AzoClose, &GenHandle2, NULL, NULL, NO_ERROR },
  209. { AzoEcho, NULL, L"Delete an object and make sure it doesn't get enumerated" },
  210. { AzoGenCreate, &GenParentHandle1,L"Name3", &GenHandle2, NO_ERROR },
  211. { AzoGenDelete, &GenParentHandle1,L"Name3", NULL, NO_ERROR },
  212. { AzoClose, &GenHandle2, NULL, NULL, NO_ERROR },
  213. { AzoGenEnum, &GenParentHandle1,NULL, &GenHandleE, NO_ERROR, OpAppChildGenEnum2 },
  214. { AzoEcho, NULL, L"Create an object whose name equals that of a deleted object" },
  215. { AzoGenCreate, &GenParentHandle1,L"Name3", &GenHandle2, NO_ERROR },
  216. { AzoClose, &GenHandle2, NULL, NULL, NO_ERROR },
  217. { AzoGenEnum, &GenParentHandle1,NULL, &GenHandleE, NO_ERROR, OpAppChildGenEnum2 },
  218. { AzoEcho, NULL, L"Delete an object that isn't on the tail end of the enum list" },
  219. { AzoGenDelete, &GenParentHandle1,L"Name2", NULL, NO_ERROR },
  220. { AzoGenEnum, &GenParentHandle1,NULL, &GenHandleE, NO_ERROR, OpAppChildGenEnum2 },
  221. { AzoEcho, NULL, L"Basic get/set property tests" },
  222. { AzoGenCreate, &GenParentHandle1,L"Name4", &GenHandle1, NO_ERROR },
  223. { AzoGenGetProp, &GenHandle1, NULL, NULL, NO_ERROR, NULL, L"Name4", AZ_PROP_NAME },
  224. { AzoGenGetProp, &GenHandle1, NULL, NULL, NO_ERROR, NULL, L"", AZ_PROP_DESCRIPTION },
  225. { AzoGenSetProp, &GenHandle1, L"WasName4", NULL, NO_ERROR, NULL, NULL, AZ_PROP_NAME },
  226. { AzoGenSetProp, &GenHandle1, L"Nam4 Desc",NULL, NO_ERROR, NULL, NULL, AZ_PROP_DESCRIPTION },
  227. { AzoGenGetProp, &GenHandle1, NULL, NULL, NO_ERROR, NULL, L"WasName4", AZ_PROP_NAME },
  228. { AzoGenGetProp, &GenHandle1, NULL, NULL, NO_ERROR, NULL, L"Nam4 Desc", AZ_PROP_DESCRIPTION },
  229. { AzoGenEnum, &GenParentHandle1,NULL, &GenHandleE, NO_ERROR, OpAppChildGenEnum2 },
  230. { AzoClose, &GenHandle1, NULL, NULL, NO_ERROR },
  231. { AzoEcho, NULL, L"Open test" },
  232. { AzoGenOpen, &GenParentHandle1,L"Name1", &GenHandle1, NO_ERROR },
  233. { AzoGenGetProp, &GenHandle1, NULL, NULL, NO_ERROR, NULL, L"Name1", AZ_PROP_NAME },
  234. { AzoClose, &GenHandle1, NULL, NULL, NO_ERROR },
  235. { AzoGenOpen, &GenParentHandle1,L"NameBad", &GenHandle1, ERROR_NOT_FOUND },
  236. { AzoEndOfList }
  237. };
  238. //
  239. // Generic operations valid for all children of "admin manager"
  240. //
  241. OPERATION OpAdmChildGen[] = {
  242. { AzoEcho, NULL, L"Admin Manager generic Child object test" },
  243. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  244. // Do a bunch of stuff not specific to application children
  245. { AzoDupHandle, &AdminMgrHandle1, NULL, &GenParentHandle1,NO_ERROR },
  246. { AzoGoSub, NULL, NULL, NULL, NO_ERROR, OpGen },
  247. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  248. { AzoEndOfList }
  249. };
  250. OPERATION OpAdmChildGenDupName[] = {
  251. { AzoEcho, NULL, L"Test creating two objects with the same name" },
  252. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  253. { AzoGenCreate, &AdminMgrHandle1, L"Name1", &GenHandle1, NO_ERROR },
  254. { AzoGenCreate, &AdminMgrHandle1, L"Name1", &GenHandle2, ERROR_ALREADY_EXISTS },
  255. { AzoClose, &GenHandle1, NULL, NULL, NO_ERROR },
  256. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  257. { AzoEndOfList }
  258. };
  259. //
  260. // Generic operations valid for all children of "application"
  261. //
  262. OPERATION OpAppChildGen[] = {
  263. { AzoEcho, NULL, L"Application generic Child object test" },
  264. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  265. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  266. // Do a bunch of stuff not specific to application children
  267. { AzoDupHandle, &AppHandle1, NULL, &GenParentHandle1,NO_ERROR },
  268. { AzoGoSub, NULL, NULL, NULL, NO_ERROR, OpGen },
  269. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  270. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  271. { AzoEndOfList }
  272. };
  273. OPERATION OpAppChildGenHandleOpen[] = {
  274. { AzoEcho, NULL, L"Test closing the same handle twice" },
  275. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  276. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  277. { AzoDupHandle, &AdminMgrHandle1, NULL, &AdminMgrHandle2, NO_ERROR },
  278. { AzoClose, &AdminMgrHandle2, NULL, NULL, ERROR_SERVER_HAS_OPEN_HANDLES },
  279. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  280. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  281. { AzoEndOfList }
  282. };
  283. OPERATION OpAppChildGenDupName[] = {
  284. { AzoEcho, NULL, L"Test creating two objects with the same name" },
  285. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  286. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  287. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle2, ERROR_ALREADY_EXISTS },
  288. { AzoGenCreate, &AppHandle1, L"Name1", &GenHandle1, NO_ERROR },
  289. { AzoGenCreate, &AppHandle1, L"Name1", &GenHandle2, ERROR_ALREADY_EXISTS },
  290. { AzoClose, &GenHandle1, NULL, NULL, NO_ERROR },
  291. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  292. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  293. { AzoEndOfList }
  294. };
  295. OPERATION OpAppChildGenLeak[] = {
  296. { AzoEcho, NULL, L"Test leaking a handle" },
  297. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  298. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  299. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  300. { AzoEndOfList }
  301. };
  302. //
  303. // Generic operations valid for all children of "scope"
  304. //
  305. OPERATION OpScopeChildGen[] = {
  306. { AzoEcho, NULL, L"Scope generic Child object test" },
  307. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  308. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  309. { AzoScopeCreate,&AppHandle1, L"Scope 1", &ScopeHandle1, NO_ERROR },
  310. // Do a bunch of stuff not specific to scope children
  311. { AzoDupHandle, &ScopeHandle1, NULL, &GenParentHandle1,NO_ERROR },
  312. { AzoGoSub, NULL, NULL, NULL, NO_ERROR, OpGen },
  313. { AzoClose, &ScopeHandle1, NULL, NULL, NO_ERROR },
  314. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  315. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  316. { AzoEndOfList }
  317. };
  318. OPERATION OpScopeChildGenDupName[] = {
  319. { AzoEcho, NULL, L"Test creating two objects with the same name" },
  320. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  321. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  322. { AzoScopeCreate,&AppHandle1, L"Scope 1", &ScopeHandle1, NO_ERROR },
  323. { AzoGenCreate, &ScopeHandle1, L"Name1", &GenHandle1, NO_ERROR },
  324. { AzoGenCreate, &ScopeHandle1, L"Name1", &GenHandle2, ERROR_ALREADY_EXISTS },
  325. { AzoClose, &GenHandle1, NULL, NULL, NO_ERROR },
  326. { AzoClose, &ScopeHandle1, NULL, NULL, NO_ERROR },
  327. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  328. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  329. { AzoEndOfList }
  330. };
  331. //
  332. // Specific tests for Operation objects
  333. //
  334. OPERATION OpOperation[] = {
  335. { AzoEcho, NULL, L"Operation object specific tests" },
  336. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  337. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  338. { AzoOpCreate, &AppHandle1, L"Oper 1", &OpHandle1, NO_ERROR },
  339. { AzoOpGetProp, &OpHandle1, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Zero, AZ_PROP_OPERATION_ID },
  340. { AzoOpSetProp, &OpHandle1, (LPWSTR)&Eight, NULL, NO_ERROR, NULL, NULL, AZ_PROP_OPERATION_ID },
  341. { AzoOpGetProp, &OpHandle1, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Eight, AZ_PROP_OPERATION_ID },
  342. { AzoClose, &OpHandle1, NULL, NULL, NO_ERROR },
  343. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  344. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  345. { AzoEndOfList }
  346. };
  347. //
  348. // Generic test of the ability of one object to link to another
  349. // AzoTestLink is the only opcode that can link to this subroutine of commands
  350. //
  351. AZ_STRING_ARRAY EmptyStringArray = { 0, NULL };
  352. ULONG TestLinkOpcodeOffset;
  353. ULONG TestLinkPropId;
  354. AZ_HANDLE TestLinkHandleP;
  355. AZ_HANDLE TestLinkHandleA;
  356. WCHAR TestLinkObjectName[1000];
  357. LPWSTR Object2x[] = { L"Object 2" };
  358. AZ_STRING_ARRAY Object2 = { 1, Object2x };
  359. LPWSTR Object3x[] = { L"Object 3" };
  360. AZ_STRING_ARRAY Object3 = { 1, Object3x };
  361. LPWSTR Object23x[] = { L"Object 2", L"Object 3" };
  362. AZ_STRING_ARRAY Object23 = { 2, Object23x };
  363. LPWSTR Object123x[] = { L"Object 1", L"Object 2", L"Object 3" };
  364. AZ_STRING_ARRAY Object123 = { 3, Object123x };
  365. LPWSTR Object123456x[] = { L"Object 1", L"Object 2", L"Object 3", L"Object 4", L"Object 5", L"Object 6" };
  366. AZ_STRING_ARRAY Object123456 = { 6, Object123456x };
  367. OPERATION OpTestLink[] = {
  368. { AzoEcho, NULL, L"Create some objects to link the object to" },
  369. { AzoTlCreate, &TestLinkHandleP, L"Object 1", &OpHandle1, NO_ERROR },
  370. { AzoClose, &OpHandle1, NULL, NULL, NO_ERROR },
  371. { AzoTlCreate, &TestLinkHandleP, L"Object 2", &OpHandle1, NO_ERROR },
  372. { AzoClose, &OpHandle1, NULL, NULL, NO_ERROR },
  373. { AzoTlCreate, &TestLinkHandleP, L"Object 3", &OpHandle1, NO_ERROR },
  374. { AzoClose, &OpHandle1, NULL, NULL, NO_ERROR },
  375. { AzoEcho, NULL, L"Reference an object that doesn't exist" },
  376. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&EmptyStringArray, 1 },
  377. { AzoGenSetProp, &TestLinkHandleA, L"random", NULL, ERROR_INVALID_PARAMETER, NULL, NULL, 1 },
  378. { AzoGenAddProp, &TestLinkHandleA, L"random", NULL, ERROR_NOT_FOUND, NULL, NULL, 1 },
  379. { AzoEcho, NULL, L"Add and remove several objects" },
  380. { AzoGenAddProp, &TestLinkHandleA, L"Object 2", NULL, NO_ERROR, NULL, NULL, 1 },
  381. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Object2, 1 },
  382. { AzoGenAddProp, &TestLinkHandleA, L"Object 3", NULL, NO_ERROR, NULL, NULL, 1 },
  383. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Object23, 1 },
  384. { AzoGenAddProp, &TestLinkHandleA, L"Object 1", NULL, NO_ERROR, NULL, NULL, 1 },
  385. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Object123, 1 },
  386. { AzoGenRemProp, &TestLinkHandleA, L"Object 1", NULL, NO_ERROR, NULL, NULL, 1 },
  387. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Object23, 1 },
  388. { AzoGenRemProp, &TestLinkHandleA, L"Object 2", NULL, NO_ERROR, NULL, NULL, 1 },
  389. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Object3, 1 },
  390. #if 0
  391. // This test has a couple problems.
  392. // It assumes that the linked-to and linked-from objects have the same parents
  393. // It assumes that an Open returns the same handle value as a previous close
  394. { AzoEcho, NULL, L"Ensure the reference is still there after a close" },
  395. { AzoClose, &TestLinkHandleA, NULL, NULL, NO_ERROR },
  396. { AzoGenOpen, &TestLinkHandleP, TestLinkObjectName, &TestLinkHandleA, NO_ERROR },
  397. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Object3, 1 },
  398. #endif // 0
  399. { AzoEcho, NULL, L"Add an item that already exists" },
  400. { AzoGenAddProp, &TestLinkHandleA, L"Object 3", NULL, ERROR_ALREADY_EXISTS, NULL, NULL, 1 },
  401. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Object3, 1 },
  402. { AzoGenRemProp, &TestLinkHandleA, L"Object 3", NULL, NO_ERROR, NULL, NULL, 1 },
  403. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&EmptyStringArray, 1 },
  404. { AzoEcho, NULL, L"Try more than 4 since reference buckets come in multiples of 4" },
  405. { AzoTlCreate, &TestLinkHandleP, L"Object 4", &OpHandle1, NO_ERROR },
  406. { AzoClose, &OpHandle1, NULL, NULL, NO_ERROR },
  407. { AzoTlCreate, &TestLinkHandleP, L"Object 5", &OpHandle1, NO_ERROR },
  408. { AzoClose, &OpHandle1, NULL, NULL, NO_ERROR },
  409. { AzoTlCreate, &TestLinkHandleP, L"Object 6", &OpHandle1, NO_ERROR },
  410. { AzoClose, &OpHandle1, NULL, NULL, NO_ERROR },
  411. { AzoGenAddProp, &TestLinkHandleA, L"Object 1", NULL, NO_ERROR, NULL, NULL, 1 },
  412. { AzoGenAddProp, &TestLinkHandleA, L"Object 4", NULL, NO_ERROR, NULL, NULL, 1 },
  413. { AzoGenAddProp, &TestLinkHandleA, L"Object 2", NULL, NO_ERROR, NULL, NULL, 1 },
  414. { AzoGenAddProp, &TestLinkHandleA, L"Object 5", NULL, NO_ERROR, NULL, NULL, 1 },
  415. { AzoGenAddProp, &TestLinkHandleA, L"Object 3", NULL, NO_ERROR, NULL, NULL, 1 },
  416. { AzoGenAddProp, &TestLinkHandleA, L"Object 6", NULL, NO_ERROR, NULL, NULL, 1 },
  417. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Object123456, 1 },
  418. { AzoTlDelete, &TestLinkHandleP, L"Object 1", NULL, NO_ERROR, NULL, NULL, 1 },
  419. { AzoTlDelete, &TestLinkHandleP, L"Object 4", NULL, NO_ERROR, NULL, NULL, 1 },
  420. { AzoTlDelete, &TestLinkHandleP, L"Object 2", NULL, NO_ERROR, NULL, NULL, 1 },
  421. { AzoTlDelete, &TestLinkHandleP, L"Object 5", NULL, NO_ERROR, NULL, NULL, 1 },
  422. { AzoTlDelete, &TestLinkHandleP, L"Object 3", NULL, NO_ERROR, NULL, NULL, 1 },
  423. { AzoTlDelete, &TestLinkHandleP, L"Object 6", NULL, NO_ERROR, NULL, NULL, 1 },
  424. { AzoEndOfList }
  425. };
  426. //
  427. // Generic test of the ability of an object to link to a sid
  428. // AzoTestLink is the only opcode that can link to this subroutine of commands
  429. //
  430. SID Sid1 = { 1, 1, {1}, 1 };
  431. SID Sid2 = { 1, 1, {1}, 2 };
  432. SID Sid3 = { 1, 1, {1}, 3 };
  433. SID Sid4 = { 1, 1, {1}, 4 };
  434. SID Sid5 = { 1, 1, {1}, 5 };
  435. SID Sid6 = { 1, 1, {1}, 6 };
  436. PSID Sid2x[] = { &Sid2 };
  437. AZ_SID_ARRAY Sid2Array = { 1, Sid2x };
  438. PSID Sid3x[] = { &Sid3 };
  439. AZ_SID_ARRAY Sid3Array = { 1, Sid3x };
  440. PSID Sid23x[] = { &Sid2, &Sid3 };
  441. AZ_SID_ARRAY Sid23Array = { 2, Sid23x };
  442. PSID Sid123x[] = { &Sid1, &Sid2, &Sid3 };
  443. AZ_SID_ARRAY Sid123Array = { 3, Sid123x };
  444. PSID Sid123456x[] = { &Sid1, &Sid2, &Sid3, &Sid4, &Sid5, &Sid6 };
  445. AZ_SID_ARRAY Sid123456Array = { 6, Sid123456x };
  446. OPERATION OpTestSid[] = {
  447. { AzoEcho, NULL, L"Add and remove several links to sids" },
  448. { AzoGenAddProp, &TestLinkHandleA, (LPWSTR)&Sid2, NULL, NO_ERROR, NULL, NULL, 1 },
  449. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Sid2Array, 1 },
  450. { AzoGenAddProp, &TestLinkHandleA, (LPWSTR)&Sid3, NULL, NO_ERROR, NULL, NULL, 1 },
  451. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Sid23Array, 1 },
  452. { AzoGenAddProp, &TestLinkHandleA, (LPWSTR)&Sid1, NULL, NO_ERROR, NULL, NULL, 1 },
  453. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Sid123Array, 1 },
  454. { AzoGenRemProp, &TestLinkHandleA, (LPWSTR)&Sid1, NULL, NO_ERROR, NULL, NULL, 1 },
  455. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Sid23Array, 1 },
  456. { AzoGenRemProp, &TestLinkHandleA, (LPWSTR)&Sid2, NULL, NO_ERROR, NULL, NULL, 1 },
  457. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Sid3Array, 1 },
  458. { AzoEcho, NULL, L"Add a link that already exists" },
  459. { AzoGenAddProp, &TestLinkHandleA, (LPWSTR)&Sid3, NULL, ERROR_ALREADY_EXISTS, NULL, NULL, 1 },
  460. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Sid3Array, 1 },
  461. { AzoGenRemProp, &TestLinkHandleA, (LPWSTR)&Sid3, NULL, NO_ERROR, NULL, NULL, 1 },
  462. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&EmptyStringArray, 1 },
  463. { AzoEcho, NULL, L"Try more than 4 since reference buckets come in multiples of 4" },
  464. { AzoGenAddProp, &TestLinkHandleA, (LPWSTR)&Sid1, NULL, NO_ERROR, NULL, NULL, 1 },
  465. { AzoGenAddProp, &TestLinkHandleA, (LPWSTR)&Sid4, NULL, NO_ERROR, NULL, NULL, 1 },
  466. { AzoGenAddProp, &TestLinkHandleA, (LPWSTR)&Sid2, NULL, NO_ERROR, NULL, NULL, 1 },
  467. { AzoGenAddProp, &TestLinkHandleA, (LPWSTR)&Sid5, NULL, NO_ERROR, NULL, NULL, 1 },
  468. { AzoGenAddProp, &TestLinkHandleA, (LPWSTR)&Sid3, NULL, NO_ERROR, NULL, NULL, 1 },
  469. { AzoGenAddProp, &TestLinkHandleA, (LPWSTR)&Sid6, NULL, NO_ERROR, NULL, NULL, 1 },
  470. { AzoGenGetProp, &TestLinkHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&Sid123456Array, 1 },
  471. { AzoEndOfList }
  472. };
  473. //
  474. // Specific tests for Task objects
  475. //
  476. OPERATION OpTask[] = {
  477. { AzoEcho, NULL, L"Task object specific tests" },
  478. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  479. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  480. { AzoTaskCreate, &AppHandle1, L"Task 1", &TaskHandle1, NO_ERROR },
  481. { AzoTaskGetProp, &TaskHandle1, NULL, NULL, NO_ERROR, NULL, L"", AZ_PROP_TASK_BIZRULE },
  482. { AzoTaskSetProp, &TaskHandle1, L"Rule1", NULL, NO_ERROR, NULL, NULL, AZ_PROP_TASK_BIZRULE },
  483. { AzoTaskGetProp, &TaskHandle1, NULL, NULL, NO_ERROR, NULL, L"Rule1", AZ_PROP_TASK_BIZRULE },
  484. { AzoEcho, NULL, L"Try an invalid language" },
  485. { AzoTaskGetProp, &TaskHandle1, NULL, NULL, NO_ERROR, NULL, L"", AZ_PROP_TASK_BIZRULE_LANGUAGE },
  486. { AzoTaskSetProp, &TaskHandle1, L"LANG1", NULL, ERROR_INVALID_PARAMETER, NULL, NULL, AZ_PROP_TASK_BIZRULE_LANGUAGE },
  487. { AzoTaskGetProp, &TaskHandle1, NULL, NULL, NO_ERROR, NULL, L"", AZ_PROP_TASK_BIZRULE_LANGUAGE },
  488. { AzoEcho, NULL, L"Try the valid languages" },
  489. { AzoTaskSetProp, &TaskHandle1, L"VBScript", NULL, NO_ERROR, NULL, NULL, AZ_PROP_TASK_BIZRULE_LANGUAGE },
  490. { AzoTaskGetProp, &TaskHandle1, NULL, NULL, NO_ERROR, NULL, L"VBScript", AZ_PROP_TASK_BIZRULE_LANGUAGE },
  491. { AzoTaskSetProp, &TaskHandle1, L"Jscript", NULL, NO_ERROR, NULL, L"", AZ_PROP_TASK_BIZRULE_LANGUAGE },
  492. { AzoTaskGetProp, &TaskHandle1, NULL, NULL, NO_ERROR, NULL, L"Jscript", AZ_PROP_TASK_BIZRULE_LANGUAGE },
  493. { AzoTestLink, &AppHandle1, (LPWSTR)"Operation", &TaskHandle1, AzoOp, OpTestLink, L"Task 1", AZ_PROP_TASK_OPERATIONS },
  494. { AzoClose, &TaskHandle1, NULL, NULL, NO_ERROR },
  495. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  496. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  497. { AzoEndOfList }
  498. };
  499. //
  500. // Specific tests for Group objects
  501. //
  502. //
  503. // Group object tests that are agnostic about the parent object
  504. // Requires GenParentHandle1 to already be set
  505. //
  506. OPERATION OpGenGroup[] = {
  507. { AzoEcho, NULL, L"Group object specific tests" },
  508. { AzoGroupCreate, &GenParentHandle1, L"Group A", &GroupHandleA, NO_ERROR },
  509. { AzoEcho, NULL, L"Create some groups to link the group to" },
  510. { AzoGroupCreate, &GenParentHandle1, L"Group 1", &GroupHandle1, NO_ERROR },
  511. { AzoClose, &GroupHandle1, NULL, NULL, NO_ERROR },
  512. { AzoGroupCreate, &GenParentHandle1, L"Group 2", &GroupHandle1, NO_ERROR },
  513. { AzoClose, &GroupHandle1, NULL, NULL, NO_ERROR },
  514. { AzoGroupCreate, &GenParentHandle1, L"Group 3", &GroupHandle1, NO_ERROR },
  515. { AzoClose, &GroupHandle1, NULL, NULL, NO_ERROR },
  516. { AzoEcho, NULL, L"Add membership to a group with no grouptype" },
  517. { AzoGroupAddProp, &GroupHandleA, L"Group 1", NULL, ERROR_INVALID_PARAMETER, NULL, NULL, AZ_PROP_GROUP_APP_MEMBERS },
  518. { AzoGroupAddProp, &GroupHandleA, (LPWSTR)&Sid1, NULL, ERROR_INVALID_PARAMETER, NULL, NULL, AZ_PROP_GROUP_MEMBERS },
  519. { AzoGroupSetProp, &GroupHandleA, (LPWSTR)&Eight,NULL, ERROR_INVALID_PARAMETER, NULL, NULL, AZ_PROP_GROUP_TYPE },
  520. { AzoGroupSetProp, &GroupHandleA, (LPWSTR)&GtMem,NULL, NO_ERROR, NULL, NULL, AZ_PROP_GROUP_TYPE },
  521. { AzoEcho, NULL, L"Reference ourself" },
  522. { AzoGroupGetProp, &GroupHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&EmptyStringArray, AZ_PROP_GROUP_APP_MEMBERS },
  523. { AzoGroupGetProp, &GroupHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&EmptyStringArray, AZ_PROP_GROUP_MEMBERS },
  524. { AzoGroupAddProp, &GroupHandleA, L"Group A", NULL, ERROR_DS_LOOP_DETECT, NULL, NULL, AZ_PROP_GROUP_APP_MEMBERS },
  525. { AzoTestLink, &GenParentHandle1, (LPWSTR)"Group", &GroupHandleA, AzoGroup, OpTestLink, L"Group A", AZ_PROP_GROUP_APP_MEMBERS },
  526. { AzoTestLink, &GenParentHandle1, (LPWSTR)"Sid", &GroupHandleA, AzoGroup, OpTestSid, L"Group A", AZ_PROP_GROUP_MEMBERS },
  527. { AzoEcho, NULL, L"Same as above, but for the non-members attribute" },
  528. { AzoGroupGetProp, &GroupHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&EmptyStringArray, AZ_PROP_GROUP_APP_NON_MEMBERS },
  529. { AzoGroupGetProp, &GroupHandleA, NULL, NULL, NO_ERROR, NULL, (LPWSTR)&EmptyStringArray, AZ_PROP_GROUP_NON_MEMBERS },
  530. { AzoGroupAddProp, &GroupHandleA, L"Group A", NULL, ERROR_DS_LOOP_DETECT, NULL, NULL, AZ_PROP_GROUP_APP_NON_MEMBERS },
  531. { AzoTestLink, &GenParentHandle1, (LPWSTR)"Group", &GroupHandleA, AzoGroup, OpTestLink, L"Group A", AZ_PROP_GROUP_APP_NON_MEMBERS },
  532. { AzoTestLink, &GenParentHandle1, (LPWSTR)"Sid", &GroupHandleA, AzoGroup, OpTestSid, L"Group A", AZ_PROP_GROUP_NON_MEMBERS },
  533. { AzoEcho, NULL, L"Set LdapQuery string" },
  534. { AzoGroupGetProp, &GroupHandleA, NULL, NULL, NO_ERROR, NULL, L"", AZ_PROP_GROUP_LDAP_QUERY },
  535. { AzoGroupSetProp, &GroupHandleA, L"TheQuery", NULL, ERROR_INVALID_PARAMETER, NULL, NULL, AZ_PROP_GROUP_LDAP_QUERY },
  536. { AzoGroupSetProp, &GroupHandleA, (LPWSTR)&GtLdap,NULL, NO_ERROR, NULL, NULL, AZ_PROP_GROUP_TYPE },
  537. { AzoGroupSetProp, &GroupHandleA, L"TheQuery", NULL, NO_ERROR, NULL, NULL, AZ_PROP_GROUP_LDAP_QUERY },
  538. { AzoGroupGetProp, &GroupHandleA, NULL, NULL, NO_ERROR, NULL, L"TheQuery", AZ_PROP_GROUP_LDAP_QUERY },
  539. { AzoGroupSetProp, &GroupHandleA, (LPWSTR)&GtMem,NULL, NO_ERROR, NULL, NULL, AZ_PROP_GROUP_TYPE },
  540. { AzoGroupSetProp, &GroupHandleA, L"TheQuery", NULL, ERROR_INVALID_PARAMETER, NULL, NULL, AZ_PROP_GROUP_LDAP_QUERY },
  541. { AzoGroupSetProp, &GroupHandleA, L"", NULL, NO_ERROR, NULL, NULL, AZ_PROP_GROUP_LDAP_QUERY },
  542. { AzoEcho, NULL, L"Test loops" },
  543. { AzoGroupCreate, &GenParentHandle1, L"Group B", &GroupHandle1, NO_ERROR },
  544. { AzoGroupSetProp, &GroupHandle1, (LPWSTR)&GtMem,NULL, NO_ERROR, NULL, NULL, AZ_PROP_GROUP_TYPE },
  545. { AzoGroupAddProp, &GroupHandleA, L"Group B", NULL, NO_ERROR, NULL, NULL, AZ_PROP_GROUP_APP_MEMBERS },
  546. { AzoGroupAddProp, &GroupHandle1, L"Group A", NULL, ERROR_DS_LOOP_DETECT, NULL, NULL, AZ_PROP_GROUP_APP_MEMBERS },
  547. { AzoGroupAddProp, &GroupHandleA, L"Group B", NULL, NO_ERROR, NULL, NULL, AZ_PROP_GROUP_APP_NON_MEMBERS },
  548. { AzoGroupAddProp, &GroupHandle1, L"Group A", NULL, ERROR_DS_LOOP_DETECT, NULL, NULL, AZ_PROP_GROUP_APP_NON_MEMBERS },
  549. { AzoGroupRemProp, &GroupHandleA, L"Group B", NULL, NO_ERROR, NULL, NULL, AZ_PROP_GROUP_APP_NON_MEMBERS },
  550. { AzoGroupRemProp, &GroupHandleA, L"Group B", NULL, NO_ERROR, NULL, NULL, AZ_PROP_GROUP_APP_MEMBERS },
  551. { AzoClose, &GroupHandle1, NULL, NULL, NO_ERROR },
  552. { AzoClose, &GroupHandleA, NULL, NULL, NO_ERROR },
  553. { AzoEndOfList }
  554. };
  555. // Tests for groups that are children of an admin manager
  556. OPERATION OpAdmGroup[] = {
  557. { AzoEcho, NULL, L"Group objects that are children of an admin manager" },
  558. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  559. // Do a bunch of stuff not specific to application children
  560. { AzoDupHandle, &AdminMgrHandle1, NULL, &GenParentHandle1,NO_ERROR },
  561. { AzoGoSub, NULL, NULL, NULL, NO_ERROR, OpGenGroup },
  562. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  563. { AzoEndOfList }
  564. };
  565. // Tests for groups that are children of an application
  566. OPERATION OpAppGroup[] = {
  567. { AzoEcho, NULL, L"Group objects that are children of an application" },
  568. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  569. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  570. // Do a bunch of stuff not specific to application children
  571. { AzoDupHandle, &AppHandle1, NULL, &GenParentHandle1,NO_ERROR },
  572. { AzoGoSub, NULL, NULL, NULL, NO_ERROR, OpGenGroup },
  573. { AzoEcho, NULL, L"Test linking to groups that are children of the same admin manager as this group." },
  574. { AzoGroupOpen, &AppHandle1, L"Group A", &GroupHandleA, NO_ERROR },
  575. { AzoTestLink, &AdminMgrHandle1, (LPWSTR)"Group", &GroupHandleA, AzoGroup, OpTestLink, L"Group A", AZ_PROP_GROUP_APP_MEMBERS },
  576. { AzoTestLink, &AdminMgrHandle1, (LPWSTR)"Group", &GroupHandleA, AzoGroup, OpTestLink, L"Group A", AZ_PROP_GROUP_APP_NON_MEMBERS },
  577. { AzoClose, &GroupHandleA, NULL, NULL, NO_ERROR },
  578. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  579. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  580. { AzoEndOfList }
  581. };
  582. // Tests for groups that are children of a scope
  583. OPERATION OpScopeGroup[] = {
  584. { AzoEcho, NULL, L"Group objects that are children of an application" },
  585. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  586. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  587. { AzoScopeCreate, &AppHandle1, L"Scope 1", &ScopeHandle1, NO_ERROR },
  588. // Do a bunch of stuff not specific to application children
  589. { AzoDupHandle, &ScopeHandle1, NULL, &GenParentHandle1,NO_ERROR },
  590. { AzoGoSub, NULL, NULL, NULL, NO_ERROR, OpGenGroup },
  591. { AzoEcho, NULL, L"Test linking to groups that are children of the same admin manager as this group." },
  592. { AzoGroupOpen, &ScopeHandle1, L"Group A", &GroupHandleA, NO_ERROR },
  593. { AzoTestLink, &AdminMgrHandle1, (LPWSTR)"Group", &GroupHandleA, AzoGroup, OpTestLink, L"Group A", AZ_PROP_GROUP_APP_MEMBERS },
  594. { AzoTestLink, &AdminMgrHandle1, (LPWSTR)"Group", &GroupHandleA, AzoGroup, OpTestLink, L"Group A", AZ_PROP_GROUP_APP_NON_MEMBERS },
  595. { AzoClose, &GroupHandleA, NULL, NULL, NO_ERROR },
  596. { AzoEcho, NULL, L"Test linking to groups that are children of the same application as this group." },
  597. { AzoGroupOpen, &ScopeHandle1, L"Group A", &GroupHandleA, NO_ERROR },
  598. { AzoTestLink, &AppHandle1, (LPWSTR)"Group", &GroupHandleA, AzoGroup, OpTestLink, L"Group A", AZ_PROP_GROUP_APP_MEMBERS },
  599. { AzoTestLink, &AppHandle1, (LPWSTR)"Group", &GroupHandleA, AzoGroup, OpTestLink, L"Group A", AZ_PROP_GROUP_APP_NON_MEMBERS },
  600. { AzoClose, &GroupHandleA, NULL, NULL, NO_ERROR },
  601. { AzoClose, &ScopeHandle1, NULL, NULL, NO_ERROR },
  602. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  603. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  604. { AzoEndOfList }
  605. };
  606. //
  607. // Specific tests for Role objects
  608. //
  609. // Tests for Roles that are children of an application
  610. OPERATION OpAppRole[] = {
  611. { AzoEcho, NULL, L"Role objects that are children of an application" },
  612. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  613. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  614. { AzoRoleCreate, &AppHandle1, L"Role A", &RoleHandleA, NO_ERROR },
  615. // Test linking roles to groups
  616. { AzoEcho, NULL, L"Test linking to groups that are children of the same admin manager as the role object." },
  617. { AzoTestLink, &AdminMgrHandle1, (LPWSTR)"Group", &RoleHandleA, AzoGroup, OpTestLink, L"Role A", AZ_PROP_ROLE_APP_MEMBERS },
  618. { AzoEcho, NULL, L"Test linking to groups that are children of the same application as the role object." },
  619. { AzoTestLink, &AppHandle1, (LPWSTR)"Group", &RoleHandleA, AzoGroup, OpTestLink, L"Role A", AZ_PROP_ROLE_APP_MEMBERS },
  620. { AzoEcho, NULL, L"Test linking to SIDs." },
  621. { AzoTestLink, &AdminMgrHandle1, (LPWSTR)"Sid", &RoleHandleA, AzoGroup, OpTestSid, L"Role A", AZ_PROP_ROLE_MEMBERS },
  622. // Test linking roles to operations
  623. { AzoTestLink, &AppHandle1, (LPWSTR)"Operation", &RoleHandleA, AzoOp, OpTestLink, L"Role A", AZ_PROP_ROLE_OPERATIONS },
  624. // Test linking roles to scopes
  625. { AzoTestLink, &AppHandle1, (LPWSTR)"Scope", &RoleHandleA, AzoScope, OpTestLink, L"Role A", AZ_PROP_ROLE_SCOPES },
  626. { AzoClose, &RoleHandleA, NULL, NULL, NO_ERROR },
  627. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  628. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  629. { AzoEndOfList }
  630. };
  631. // Tests for Roles that are children of an scope
  632. OPERATION OpScopeRole[] = {
  633. { AzoEcho, NULL, L"Role objects that are children of an application" },
  634. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  635. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  636. { AzoScopeCreate, &AppHandle1, L"Scope 1", &ScopeHandle1, NO_ERROR },
  637. { AzoRoleCreate, &ScopeHandle1, L"Role A", &RoleHandleA, NO_ERROR },
  638. // Test linking roles to groups
  639. { AzoEcho, NULL, L"Test linking to groups that are children of the same scope object as the role object." },
  640. { AzoTestLink, &ScopeHandle1, (LPWSTR)"Group", &RoleHandleA, AzoGroup, OpTestLink, L"Role A", AZ_PROP_ROLE_APP_MEMBERS },
  641. { AzoEcho, NULL, L"Test linking to groups that are children of the same application as the role object." },
  642. { AzoTestLink, &AppHandle1, (LPWSTR)"Group", &RoleHandleA, AzoGroup, OpTestLink, L"Role A", AZ_PROP_ROLE_APP_MEMBERS },
  643. { AzoEcho, NULL, L"Test linking to SIDs." },
  644. { AzoTestLink, &AdminMgrHandle1, (LPWSTR)"Sid", &RoleHandleA, AzoGroup, OpTestSid, L"Role A", AZ_PROP_ROLE_MEMBERS },
  645. { AzoEcho, NULL, L"Test linking to groups that are children of the same admin manager as the role object." },
  646. { AzoTestLink, &AdminMgrHandle1, (LPWSTR)"Group", &RoleHandleA, AzoGroup, OpTestLink, L"Role A", AZ_PROP_ROLE_APP_MEMBERS },
  647. // Test linking roles to operations
  648. { AzoTestLink, &AppHandle1, (LPWSTR)"Operation", &RoleHandleA, AzoOp, OpTestLink, L"Role A", AZ_PROP_ROLE_OPERATIONS },
  649. // Test linking roles to scopes
  650. { AzoTestLink, &AppHandle1, (LPWSTR)"Scope", &RoleHandleA, AzoScope, OpTestLink, L"Role A", AZ_PROP_ROLE_SCOPES },
  651. { AzoClose, &RoleHandleA, NULL, NULL, NO_ERROR },
  652. { AzoClose, &ScopeHandle1, NULL, NULL, NO_ERROR },
  653. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  654. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  655. { AzoEndOfList }
  656. };
  657. //
  658. // Specific tests for JunctionPoint objects
  659. //
  660. OPERATION OpAppJunctionPoint[] = {
  661. { AzoEcho, NULL, L"JunctionPoint object specific tests" },
  662. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  663. { AzoAppCreate, &AdminMgrHandle1, L"App 1", &AppHandle1, NO_ERROR },
  664. { AzoAppCreate, &AdminMgrHandle1, L"App 3", &AppHandle2, NO_ERROR },
  665. { AzoClose, &AppHandle2, NULL, NULL, NO_ERROR },
  666. { AzoAppCreate, &AdminMgrHandle1, L"App 2", &AppHandle2, NO_ERROR },
  667. { AzoJPCreate, &AppHandle1, L"JunctionPoint 1", &JPHandle1, NO_ERROR },
  668. { AzoJPGetProp, &JPHandle1, NULL, NULL, NO_ERROR, NULL, L"", AZ_PROP_JUNCTION_POINT_APPLICATION },
  669. { AzoJPSetProp, &JPHandle1, L"App 2", NULL, NO_ERROR, NULL, NULL, AZ_PROP_JUNCTION_POINT_APPLICATION },
  670. { AzoJPGetProp, &JPHandle1, NULL, NULL, NO_ERROR, NULL, L"App 2", AZ_PROP_JUNCTION_POINT_APPLICATION },
  671. { AzoEcho, NULL, L"Ensure setting the attribute really changes it" },
  672. { AzoJPSetProp, &JPHandle1, L"App 3", NULL, NO_ERROR, NULL, NULL, AZ_PROP_JUNCTION_POINT_APPLICATION },
  673. { AzoJPGetProp, &JPHandle1, NULL, NULL, NO_ERROR, NULL, L"App 3", AZ_PROP_JUNCTION_POINT_APPLICATION },
  674. { AzoEcho, NULL, L"Ensure deleting the app deletes the reference" },
  675. { AzoAppDelete, &AdminMgrHandle1, L"App 3", NULL, NO_ERROR },
  676. { AzoJPGetProp, &JPHandle1, NULL, NULL, NO_ERROR, NULL, L"", AZ_PROP_JUNCTION_POINT_APPLICATION },
  677. { AzoEcho, NULL, L"Link a junction point to its own app" },
  678. { AzoJPSetProp, &JPHandle1, L"App 1", NULL, ERROR_DS_LOOP_DETECT, NULL, NULL, AZ_PROP_JUNCTION_POINT_APPLICATION },
  679. { AzoEcho, NULL, L"Detect a more complex cycle" },
  680. { AzoJPSetProp, &JPHandle1, L"App 2", NULL, NO_ERROR, NULL, NULL, AZ_PROP_JUNCTION_POINT_APPLICATION },
  681. { AzoJPCreate, &AppHandle2, L"JunctionPoint A", &JPHandleA, NO_ERROR },
  682. { AzoJPSetProp, &JPHandleA, L"App 1", NULL, ERROR_DS_LOOP_DETECT, NULL, NULL, AZ_PROP_JUNCTION_POINT_APPLICATION },
  683. { AzoJPCreate, &AppHandle2, L"JunctionPoint B", &JPHandleB, NO_ERROR },
  684. { AzoJPSetProp, &JPHandleA, L"App 1", NULL, ERROR_DS_LOOP_DETECT, NULL, NULL, AZ_PROP_JUNCTION_POINT_APPLICATION },
  685. { AzoJPSetProp, &JPHandleB, L"App 1", NULL, ERROR_DS_LOOP_DETECT, NULL, NULL, AZ_PROP_JUNCTION_POINT_APPLICATION },
  686. { AzoClose, &JPHandleA, NULL, NULL, NO_ERROR },
  687. { AzoClose, &JPHandleB, NULL, NULL, NO_ERROR },
  688. { AzoClose, &JPHandle1, NULL, NULL, NO_ERROR },
  689. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  690. { AzoClose, &AppHandle2, NULL, NULL, NO_ERROR },
  691. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  692. { AzoEndOfList }
  693. };
  694. //
  695. // Ensure certain objects can't share names
  696. //
  697. OPERATION OpShare[] = {
  698. { AzoEcho, NULL, L"Certain objects can't share names" },
  699. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  700. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  701. { AzoEcho, NULL, L"Create some tasks and ops as a starting point" },
  702. { AzoTaskCreate, &AppHandle1, L"Task 1", &TaskHandle1, NO_ERROR },
  703. { AzoClose, &TaskHandle1, NULL, NULL, NO_ERROR },
  704. { AzoOpCreate, &AppHandle1, L"Op 1", &OpHandle1, NO_ERROR },
  705. { AzoClose, &OpHandle1, NULL, NULL, NO_ERROR },
  706. { AzoEcho, NULL, L"Task and operations can't share names" },
  707. { AzoTaskCreate, &AppHandle1, L"Op 1", &TaskHandle1, ERROR_ALREADY_EXISTS },
  708. { AzoOpCreate, &AppHandle1, L"Task 1", &OpHandle1, ERROR_ALREADY_EXISTS },
  709. { AzoEcho, NULL, L"Create some groups as a starting point" },
  710. { AzoGroupCreate, &AdminMgrHandle1, L"Group Adm",&GroupHandle1, NO_ERROR },
  711. { AzoClose, &GroupHandle1, NULL, NULL, NO_ERROR },
  712. { AzoGroupCreate, &AppHandle1, L"Group App",&GroupHandle1, NO_ERROR },
  713. { AzoClose, &GroupHandle1, NULL, NULL, NO_ERROR },
  714. { AzoEcho, NULL, L"Create an app group that conflicts with an adm group, etc" },
  715. { AzoGroupCreate, &AppHandle1, L"Group Adm",&GroupHandleA, ERROR_ALREADY_EXISTS },
  716. { AzoGroupCreate, &AdminMgrHandle1, L"Group App",&GroupHandleA, ERROR_ALREADY_EXISTS },
  717. { AzoEcho, NULL, L"Create a scope group" },
  718. { AzoScopeCreate, &AppHandle1, L"Scope 1", &ScopeHandle1, NO_ERROR },
  719. { AzoGroupCreate, &ScopeHandle1, L"Group Scp",&GroupHandle1, NO_ERROR },
  720. { AzoClose, &GroupHandle1, NULL, NULL, NO_ERROR },
  721. { AzoEcho, NULL, L"Create a scope group that conflicts with an adm group, etc" },
  722. { AzoGroupCreate, &ScopeHandle1, L"Group Adm",&GroupHandleA, ERROR_ALREADY_EXISTS },
  723. { AzoGroupCreate, &ScopeHandle1, L"Group App",&GroupHandleA, ERROR_ALREADY_EXISTS },
  724. { AzoEcho, NULL, L"Create an app/adm group that conflicts with a scope group" },
  725. { AzoGroupCreate, &AppHandle1, L"Group Scp",&GroupHandleA, ERROR_ALREADY_EXISTS },
  726. { AzoGroupCreate, &AdminMgrHandle1, L"Group Scp",&GroupHandleA, ERROR_ALREADY_EXISTS },
  727. { AzoClose, &ScopeHandle1, NULL, NULL, NO_ERROR },
  728. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  729. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  730. { AzoEndOfList }
  731. };
  732. //
  733. // Ensure peristence works
  734. //
  735. // App object enum
  736. OPERATION OpAppEnum[] = {
  737. { AzoAppGetProp, &GenHandleE, NULL, NULL, NO_ERROR, NULL, NULL, AZ_PROP_NAME },
  738. { AzoClose, &GenHandleE, NULL, NULL, NO_ERROR },
  739. { AzoEndOfList }
  740. };
  741. // Task object enum
  742. OPERATION OpTaskEnum[] = {
  743. { AzoTaskGetProp, &GenHandleE, NULL, NULL, NO_ERROR, NULL, NULL, AZ_PROP_NAME },
  744. { AzoClose, &GenHandleE, NULL, NULL, NO_ERROR },
  745. { AzoEndOfList }
  746. };
  747. // Operation object enum
  748. OPERATION OpOpEnum[] = {
  749. { AzoOpGetProp, &GenHandleE, NULL, NULL, NO_ERROR, NULL, NULL, AZ_PROP_NAME },
  750. { AzoClose, &GenHandleE, NULL, NULL, NO_ERROR },
  751. { AzoEndOfList }
  752. };
  753. OPERATION OpPersist[] = {
  754. { AzoEcho, NULL, L"Ensure objects persist across a close" },
  755. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, AZ_ADMIN_FLAG_CREATE },
  756. { AzoAppCreate, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  757. { AzoTaskCreate, &AppHandle1, L"Task 1", &TaskHandle1, NO_ERROR },
  758. { AzoOpCreate, &AppHandle1, L"Op 1", &OpHandle1, NO_ERROR },
  759. { AzoClose, &OpHandle1, NULL, NULL, NO_ERROR },
  760. { AzoClose, &TaskHandle1, NULL, NULL, NO_ERROR },
  761. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  762. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  763. { AzoEcho, NULL, L"See if they're still there" },
  764. { AzoInit, NULL, L".\\TestFile", &AdminMgrHandle1, NO_ERROR, NULL, NULL, 0 },
  765. { AzoAppEnum, &AdminMgrHandle1, NULL, &GenHandleE, NO_ERROR, OpAppEnum },
  766. { AzoAppOpen, &AdminMgrHandle1, L"MyApp", &AppHandle1, NO_ERROR },
  767. { AzoTaskEnum, &AppHandle1, NULL, &GenHandleE, NO_ERROR, OpTaskEnum },
  768. { AzoTaskOpen, &AppHandle1, L"Task 1", &TaskHandle1, NO_ERROR },
  769. { AzoOpEnum, &AppHandle1, NULL, &GenHandleE, NO_ERROR, OpOpEnum },
  770. { AzoOpOpen, &AppHandle1, L"Op 1", &OpHandle1, NO_ERROR },
  771. { AzoClose, &OpHandle1, NULL, NULL, NO_ERROR },
  772. { AzoClose, &TaskHandle1, NULL, NULL, NO_ERROR },
  773. { AzoClose, &AppHandle1, NULL, NULL, NO_ERROR },
  774. { AzoClose, &AdminMgrHandle1, NULL, NULL, NO_ERROR },
  775. { AzoEndOfList }
  776. };
  777. VOID
  778. DumpBuffer(
  779. PVOID Buffer,
  780. DWORD BufferSize
  781. )
  782. /*++
  783. Routine Description:
  784. Dumps the buffer content on to the debugger output.
  785. Arguments:
  786. Buffer: buffer pointer.
  787. BufferSize: size of the buffer.
  788. Return Value:
  789. none
  790. --*/
  791. {
  792. #define NUM_CHARS 16
  793. DWORD i, limit;
  794. CHAR TextBuffer[NUM_CHARS + 1];
  795. LPBYTE BufferPtr = Buffer;
  796. printf("------------------------------------\n");
  797. //
  798. // Hex dump of the bytes
  799. //
  800. limit = ((BufferSize - 1) / NUM_CHARS + 1) * NUM_CHARS;
  801. for (i = 0; i < limit; i++) {
  802. if (i < BufferSize) {
  803. printf("%02x ", BufferPtr[i]);
  804. if (BufferPtr[i] < 31 ) {
  805. TextBuffer[i % NUM_CHARS] = '.';
  806. } else if (BufferPtr[i] == '\0') {
  807. TextBuffer[i % NUM_CHARS] = ' ';
  808. } else {
  809. TextBuffer[i % NUM_CHARS] = (CHAR) BufferPtr[i];
  810. }
  811. } else {
  812. printf(" ");
  813. TextBuffer[i % NUM_CHARS] = ' ';
  814. }
  815. if ((i + 1) % NUM_CHARS == 0) {
  816. TextBuffer[NUM_CHARS] = 0;
  817. printf(" %s\n", TextBuffer);
  818. }
  819. }
  820. printf("------------------------------------\n");
  821. }
  822. LPSTR
  823. FindSymbolicNameForStatus(
  824. DWORD Id
  825. )
  826. {
  827. ULONG i;
  828. i = 0;
  829. if (Id == 0) {
  830. return "STATUS_SUCCESS";
  831. }
  832. if (Id & 0xC0000000) {
  833. while (ntstatusSymbolicNames[ i ].SymbolicName) {
  834. if (ntstatusSymbolicNames[ i ].MessageId == (NTSTATUS)Id) {
  835. return ntstatusSymbolicNames[ i ].SymbolicName;
  836. } else {
  837. i += 1;
  838. }
  839. }
  840. }
  841. while (winerrorSymbolicNames[ i ].SymbolicName) {
  842. if (winerrorSymbolicNames[ i ].MessageId == Id) {
  843. return winerrorSymbolicNames[ i ].SymbolicName;
  844. } else {
  845. i += 1;
  846. }
  847. }
  848. #ifdef notdef
  849. while (neteventSymbolicNames[ i ].SymbolicName) {
  850. if (neteventSymbolicNames[ i ].MessageId == Id) {
  851. return neteventSymbolicNames[ i ].SymbolicName
  852. } else {
  853. i += 1;
  854. }
  855. }
  856. #endif // notdef
  857. return NULL;
  858. }
  859. VOID
  860. PrintStatus(
  861. NET_API_STATUS NetStatus
  862. )
  863. /*++
  864. Routine Description:
  865. Print a net status code.
  866. Arguments:
  867. NetStatus - The net status code to print.
  868. Return Value:
  869. None
  870. --*/
  871. {
  872. switch (NetStatus) {
  873. case NO_ERROR:
  874. printf( "NO_ERROR" );
  875. break;
  876. case NERR_DCNotFound:
  877. printf( "NERR_DCNotFound" );
  878. break;
  879. case ERROR_LOGON_FAILURE:
  880. printf( "ERROR_LOGON_FAILURE" );
  881. break;
  882. case ERROR_ACCESS_DENIED:
  883. printf( "ERROR_ACCESS_DENIED" );
  884. break;
  885. case ERROR_NOT_SUPPORTED:
  886. printf( "ERROR_NOT_SUPPORTED" );
  887. break;
  888. case ERROR_NO_LOGON_SERVERS:
  889. printf( "ERROR_NO_LOGON_SERVERS" );
  890. break;
  891. case ERROR_NO_SUCH_DOMAIN:
  892. printf( "ERROR_NO_SUCH_DOMAIN" );
  893. break;
  894. case ERROR_NO_TRUST_LSA_SECRET:
  895. printf( "ERROR_NO_TRUST_LSA_SECRET" );
  896. break;
  897. case ERROR_NO_TRUST_SAM_ACCOUNT:
  898. printf( "ERROR_NO_TRUST_SAM_ACCOUNT" );
  899. break;
  900. case ERROR_DOMAIN_TRUST_INCONSISTENT:
  901. printf( "ERROR_DOMAIN_TRUST_INCONSISTENT" );
  902. break;
  903. case ERROR_BAD_NETPATH:
  904. printf( "ERROR_BAD_NETPATH" );
  905. break;
  906. case ERROR_FILE_NOT_FOUND:
  907. printf( "ERROR_FILE_NOT_FOUND" );
  908. break;
  909. case NERR_NetNotStarted:
  910. printf( "NERR_NetNotStarted" );
  911. break;
  912. case NERR_WkstaNotStarted:
  913. printf( "NERR_WkstaNotStarted" );
  914. break;
  915. case NERR_ServerNotStarted:
  916. printf( "NERR_ServerNotStarted" );
  917. break;
  918. case NERR_BrowserNotStarted:
  919. printf( "NERR_BrowserNotStarted" );
  920. break;
  921. case NERR_ServiceNotInstalled:
  922. printf( "NERR_ServiceNotInstalled" );
  923. break;
  924. case NERR_BadTransactConfig:
  925. printf( "NERR_BadTransactConfig" );
  926. break;
  927. case SEC_E_NO_SPM:
  928. printf( "SEC_E_NO_SPM" );
  929. break;
  930. case SEC_E_BAD_PKGID:
  931. printf( "SEC_E_BAD_PKGID" ); break;
  932. case SEC_E_NOT_OWNER:
  933. printf( "SEC_E_NOT_OWNER" ); break;
  934. case SEC_E_CANNOT_INSTALL:
  935. printf( "SEC_E_CANNOT_INSTALL" ); break;
  936. case SEC_E_INVALID_TOKEN:
  937. printf( "SEC_E_INVALID_TOKEN" ); break;
  938. case SEC_E_CANNOT_PACK:
  939. printf( "SEC_E_CANNOT_PACK" ); break;
  940. case SEC_E_QOP_NOT_SUPPORTED:
  941. printf( "SEC_E_QOP_NOT_SUPPORTED" ); break;
  942. case SEC_E_NO_IMPERSONATION:
  943. printf( "SEC_E_NO_IMPERSONATION" ); break;
  944. case SEC_E_LOGON_DENIED:
  945. printf( "SEC_E_LOGON_DENIED" ); break;
  946. case SEC_E_UNKNOWN_CREDENTIALS:
  947. printf( "SEC_E_UNKNOWN_CREDENTIALS" ); break;
  948. case SEC_E_NO_CREDENTIALS:
  949. printf( "SEC_E_NO_CREDENTIALS" ); break;
  950. case SEC_E_MESSAGE_ALTERED:
  951. printf( "SEC_E_MESSAGE_ALTERED" ); break;
  952. case SEC_E_OUT_OF_SEQUENCE:
  953. printf( "SEC_E_OUT_OF_SEQUENCE" ); break;
  954. case SEC_E_INSUFFICIENT_MEMORY:
  955. printf( "SEC_E_INSUFFICIENT_MEMORY" ); break;
  956. case SEC_E_INVALID_HANDLE:
  957. printf( "SEC_E_INVALID_HANDLE" ); break;
  958. case SEC_E_NOT_SUPPORTED:
  959. printf( "SEC_E_NOT_SUPPORTED" ); break;
  960. default: {
  961. LPSTR Name = FindSymbolicNameForStatus( NetStatus );
  962. if ( Name == NULL ) {
  963. printf( "(%lu)", NetStatus );
  964. } else {
  965. printf( "%s", Name );
  966. }
  967. break;
  968. }
  969. }
  970. }
  971. VOID
  972. PrintIndent(
  973. IN ULONG Indentation,
  974. IN BOOLEAN Error
  975. )
  976. /*++
  977. Routine Description:
  978. Print line prefix for log file
  979. Arguments:
  980. Indentation - Number of spaces to indent text by.
  981. Error - True if this is a program failure.
  982. Return Value:
  983. None.
  984. --*/
  985. {
  986. static LPSTR Blanks = " ";
  987. printf( "%*.*s", Indentation, Indentation, Blanks );
  988. if ( Error ) {
  989. printf("[ERR] ");
  990. }
  991. }
  992. BOOL
  993. DoOperations(
  994. IN POPERATION OperationsToDo,
  995. IN ULONG Indentation,
  996. IN ULONG SpecificOpcodeOffset,
  997. IN LPSTR EchoPrefix
  998. )
  999. /*++
  1000. Routine Description:
  1001. Do a set of operations
  1002. Arguments:
  1003. OperationsToDo - a list of operations to do
  1004. Indentation - Number of spaces to indent text by.
  1005. This value increases on recursive calls.
  1006. SpecificOpcodeOffset - Specifies an amount to add to a generic opcode to map
  1007. it to a specific opcode.
  1008. EchoPrefix - Specifies a string to print before all AzoEcho strings
  1009. Return Value:
  1010. TRUE - tests completed successfully
  1011. FALSE - tests failed
  1012. --*/
  1013. {
  1014. BOOL RetVal = TRUE;
  1015. POPERATION Operation;
  1016. LPSTR OpName;
  1017. ULONG Opcode;
  1018. PVOID PropertyValue = NULL;
  1019. ULONG PropType;
  1020. #define PT_NONE 0
  1021. #define PT_LPWSTR 1
  1022. #define PT_STRING_ARRAY 2
  1023. #define PT_ULONG 3
  1024. #define PT_SID_ARRAY 4
  1025. ULONG PropertyId;
  1026. BOOLEAN WasSetProperty;
  1027. BOOLEAN WasGetProperty;
  1028. HANDLE SubmitHandle;
  1029. ULONG EnumerationContext = 0;
  1030. BOOLEAN FirstIteration = TRUE;
  1031. DWORD WinStatus;
  1032. DWORD RealWinStatus;
  1033. CHAR BigBuffer[1000];
  1034. PAZ_STRING_ARRAY StringArray1;
  1035. PAZ_STRING_ARRAY StringArray2;
  1036. PAZ_SID_ARRAY SidArray1;
  1037. PAZ_SID_ARRAY SidArray2;
  1038. ULONG i;
  1039. //
  1040. // Leave room between tests
  1041. //
  1042. if ( Indentation == 0 ) {
  1043. printf( "\n\n" );
  1044. }
  1045. //
  1046. // Loop through each of the operations
  1047. //
  1048. for ( Operation=OperationsToDo; Operation->Opcode != AzoEndOfList && RetVal; ) {
  1049. //
  1050. // Mark that this change doesn't need to be submitted
  1051. //
  1052. SubmitHandle = INVALID_HANDLE_VALUE;
  1053. //
  1054. // Compute the mapped property ID
  1055. //
  1056. if ( TestLinkPropId != 0 && Operation->PropertyId != 0 ) {
  1057. PropertyId = TestLinkPropId;
  1058. } else {
  1059. PropertyId = Operation->PropertyId;
  1060. }
  1061. //
  1062. // Setup for get/set property
  1063. //
  1064. PropType = PT_NONE;
  1065. // Do common types
  1066. if ( PropertyId == AZ_PROP_NAME ||
  1067. PropertyId == AZ_PROP_DESCRIPTION ) {
  1068. PropType = PT_LPWSTR;
  1069. }
  1070. WasSetProperty = FALSE;
  1071. WasGetProperty = FALSE;
  1072. //
  1073. // Map generic opcodes to a specific opcode
  1074. //
  1075. Opcode = Operation->Opcode;
  1076. if ( Opcode < AzoGenMax ) {
  1077. ASSERT( SpecificOpcodeOffset != 0 );
  1078. Opcode += SpecificOpcodeOffset;
  1079. } else if ( Opcode >= AzoTl && Opcode < AzoTlMax ) {
  1080. ASSERT( TestLinkOpcodeOffset != 0 );
  1081. Opcode = Opcode - AzoTl + TestLinkOpcodeOffset;
  1082. }
  1083. //
  1084. // Perform the requested operation
  1085. //
  1086. switch ( Opcode ) {
  1087. case AzoInit:
  1088. OpName = "AzInitialize";
  1089. WinStatus = AzInitialize(
  1090. AZ_ADMIN_STORE_SAMPLE, // Shouldn't be a constant
  1091. Operation->Parameter1,
  1092. PropertyId, // Flags
  1093. 0, // reserved
  1094. Operation->OutputHandle );
  1095. break;
  1096. //
  1097. // Application APIs
  1098. //
  1099. case AzoAppCreate:
  1100. OpName = "AzApplicationCreate";
  1101. WinStatus = AzApplicationCreate(
  1102. *Operation->InputHandle,
  1103. Operation->Parameter1,
  1104. 0, // reserved
  1105. Operation->OutputHandle );
  1106. SubmitHandle = *Operation->OutputHandle;
  1107. break;
  1108. case AzoAppOpen:
  1109. OpName = "AzApplicationOpen";
  1110. WinStatus = AzApplicationOpen(
  1111. *Operation->InputHandle,
  1112. Operation->Parameter1,
  1113. 0, // reserved
  1114. Operation->OutputHandle );
  1115. break;
  1116. case AzoAppEnum:
  1117. OpName = "AzApplicationEnum";
  1118. WinStatus = AzApplicationEnum(
  1119. *Operation->InputHandle,
  1120. 0, // reserved
  1121. &EnumerationContext,
  1122. Operation->OutputHandle );
  1123. break;
  1124. case AzoAppGetProp:
  1125. OpName = "AzApplicationGetProperty";
  1126. WinStatus = AzApplicationGetProperty(
  1127. *Operation->InputHandle,
  1128. PropertyId,
  1129. 0, // reserved
  1130. &PropertyValue );
  1131. WasGetProperty = TRUE;
  1132. break;
  1133. case AzoAppSetProp:
  1134. OpName = "AzApplicationSetProperty";
  1135. WinStatus = AzApplicationSetProperty(
  1136. *Operation->InputHandle,
  1137. PropertyId,
  1138. 0, // reserved
  1139. Operation->Parameter1 );
  1140. WasSetProperty = TRUE;
  1141. SubmitHandle = *Operation->InputHandle;
  1142. break;
  1143. case AzoAppDelete:
  1144. OpName = "AzApplicationDelete";
  1145. WinStatus = AzApplicationDelete(
  1146. *Operation->InputHandle,
  1147. Operation->Parameter1,
  1148. 0 ); // reserved
  1149. break;
  1150. //
  1151. // Operation APIs
  1152. //
  1153. case AzoOpCreate:
  1154. OpName = "AzOperationCreate";
  1155. WinStatus = AzOperationCreate(
  1156. *Operation->InputHandle,
  1157. Operation->Parameter1,
  1158. 0, // reserved
  1159. Operation->OutputHandle );
  1160. SubmitHandle = *Operation->OutputHandle;
  1161. break;
  1162. case AzoOpOpen:
  1163. OpName = "AzOperationOpen";
  1164. WinStatus = AzOperationOpen(
  1165. *Operation->InputHandle,
  1166. Operation->Parameter1,
  1167. 0, // reserved
  1168. Operation->OutputHandle );
  1169. break;
  1170. case AzoOpEnum:
  1171. OpName = "AzOperationEnum";
  1172. WinStatus = AzOperationEnum(
  1173. *Operation->InputHandle,
  1174. 0, // reserved
  1175. &EnumerationContext,
  1176. Operation->OutputHandle );
  1177. break;
  1178. case AzoOpGetProp:
  1179. OpName = "AzOperationGetProperty";
  1180. WinStatus = AzOperationGetProperty(
  1181. *Operation->InputHandle,
  1182. PropertyId,
  1183. 0, // reserved
  1184. &PropertyValue );
  1185. WasGetProperty = TRUE;
  1186. if ( PropertyId == AZ_PROP_OPERATION_ID ) {
  1187. PropType = PT_ULONG;
  1188. }
  1189. break;
  1190. case AzoOpSetProp:
  1191. OpName = "AzOperationSetProperty";
  1192. WinStatus = AzOperationSetProperty(
  1193. *Operation->InputHandle,
  1194. PropertyId,
  1195. 0, // reserved
  1196. Operation->Parameter1 );
  1197. WasSetProperty = TRUE;
  1198. if ( PropertyId == AZ_PROP_OPERATION_ID ) {
  1199. PropType = PT_ULONG;
  1200. }
  1201. SubmitHandle = *Operation->InputHandle;
  1202. break;
  1203. case AzoOpDelete:
  1204. OpName = "AzOperationDelete";
  1205. WinStatus = AzOperationDelete(
  1206. *Operation->InputHandle,
  1207. Operation->Parameter1,
  1208. 0 ); // reserved
  1209. break;
  1210. //
  1211. // Task APIs
  1212. //
  1213. case AzoTaskCreate:
  1214. OpName = "AzTaskCreate";
  1215. WinStatus = AzTaskCreate(
  1216. *Operation->InputHandle,
  1217. Operation->Parameter1,
  1218. 0, // reserved
  1219. Operation->OutputHandle );
  1220. SubmitHandle = *Operation->OutputHandle;
  1221. break;
  1222. case AzoTaskOpen:
  1223. OpName = "AzTaskOpen";
  1224. WinStatus = AzTaskOpen(
  1225. *Operation->InputHandle,
  1226. Operation->Parameter1,
  1227. 0, // reserved
  1228. Operation->OutputHandle );
  1229. break;
  1230. case AzoTaskEnum:
  1231. OpName = "AzTaskEnum";
  1232. WinStatus = AzTaskEnum(
  1233. *Operation->InputHandle,
  1234. 0, // reserved
  1235. &EnumerationContext,
  1236. Operation->OutputHandle );
  1237. break;
  1238. case AzoTaskGetProp:
  1239. OpName = "AzTaskGetProperty";
  1240. WinStatus = AzTaskGetProperty(
  1241. *Operation->InputHandle,
  1242. PropertyId,
  1243. 0, // reserved
  1244. &PropertyValue );
  1245. WasGetProperty = TRUE;
  1246. if ( PropertyId == AZ_PROP_TASK_BIZRULE ||
  1247. PropertyId == AZ_PROP_TASK_BIZRULE_LANGUAGE ) {
  1248. PropType = PT_LPWSTR;
  1249. } else if ( PropertyId == AZ_PROP_TASK_OPERATIONS ) {
  1250. PropType = PT_STRING_ARRAY;
  1251. }
  1252. break;
  1253. case AzoTaskSetProp:
  1254. OpName = "AzTaskSetProperty";
  1255. WinStatus = AzTaskSetProperty(
  1256. *Operation->InputHandle,
  1257. PropertyId,
  1258. 0, // reserved
  1259. Operation->Parameter1 );
  1260. WasSetProperty = TRUE;
  1261. if ( PropertyId == AZ_PROP_TASK_BIZRULE ||
  1262. PropertyId == AZ_PROP_TASK_BIZRULE_LANGUAGE ) {
  1263. PropType = PT_LPWSTR;
  1264. }
  1265. SubmitHandle = *Operation->InputHandle;
  1266. break;
  1267. case AzoTaskAddProp:
  1268. OpName = "AzTaskAddProperty";
  1269. WinStatus = AzTaskAddPropertyItem(
  1270. *Operation->InputHandle,
  1271. PropertyId,
  1272. 0, // reserved
  1273. Operation->Parameter1 );
  1274. SubmitHandle = *Operation->InputHandle;
  1275. break;
  1276. case AzoTaskRemProp:
  1277. OpName = "AzTaskRemProperty";
  1278. WinStatus = AzTaskRemovePropertyItem(
  1279. *Operation->InputHandle,
  1280. PropertyId,
  1281. 0, // reserved
  1282. Operation->Parameter1 );
  1283. SubmitHandle = *Operation->InputHandle;
  1284. break;
  1285. case AzoTaskDelete:
  1286. OpName = "AzTaskDelete";
  1287. WinStatus = AzTaskDelete(
  1288. *Operation->InputHandle,
  1289. Operation->Parameter1,
  1290. 0 ); // reserved
  1291. break;
  1292. //
  1293. // Scope APIs
  1294. //
  1295. case AzoScopeCreate:
  1296. OpName = "AzScopeCreate";
  1297. WinStatus = AzScopeCreate(
  1298. *Operation->InputHandle,
  1299. Operation->Parameter1,
  1300. 0, // reserved
  1301. Operation->OutputHandle );
  1302. SubmitHandle = *Operation->OutputHandle;
  1303. break;
  1304. case AzoScopeOpen:
  1305. OpName = "AzScopeOpen";
  1306. WinStatus = AzScopeOpen(
  1307. *Operation->InputHandle,
  1308. Operation->Parameter1,
  1309. 0, // reserved
  1310. Operation->OutputHandle );
  1311. break;
  1312. case AzoScopeEnum:
  1313. OpName = "AzScopeEnum";
  1314. WinStatus = AzScopeEnum(
  1315. *Operation->InputHandle,
  1316. 0, // reserved
  1317. &EnumerationContext,
  1318. Operation->OutputHandle );
  1319. break;
  1320. case AzoScopeGetProp:
  1321. OpName = "AzScopeGetProperty";
  1322. WinStatus = AzScopeGetProperty(
  1323. *Operation->InputHandle,
  1324. PropertyId,
  1325. 0, // reserved
  1326. &PropertyValue );
  1327. WasGetProperty = TRUE;
  1328. break;
  1329. case AzoScopeSetProp:
  1330. OpName = "AzScopeSetProperty";
  1331. WinStatus = AzScopeSetProperty(
  1332. *Operation->InputHandle,
  1333. PropertyId,
  1334. 0, // reserved
  1335. Operation->Parameter1 );
  1336. WasSetProperty = TRUE;
  1337. SubmitHandle = *Operation->InputHandle;
  1338. break;
  1339. case AzoScopeDelete:
  1340. OpName = "AzScopeDelete";
  1341. WinStatus = AzScopeDelete(
  1342. *Operation->InputHandle,
  1343. Operation->Parameter1,
  1344. 0 ); // reserved
  1345. break;
  1346. //
  1347. // Group APIs
  1348. //
  1349. case AzoGroupCreate:
  1350. OpName = "AzGroupCreate";
  1351. WinStatus = AzGroupCreate(
  1352. *Operation->InputHandle,
  1353. Operation->Parameter1,
  1354. 0, // reserved
  1355. Operation->OutputHandle );
  1356. SubmitHandle = *Operation->OutputHandle;
  1357. break;
  1358. case AzoGroupOpen:
  1359. OpName = "AzGroupOpen";
  1360. WinStatus = AzGroupOpen(
  1361. *Operation->InputHandle,
  1362. Operation->Parameter1,
  1363. 0, // reserved
  1364. Operation->OutputHandle );
  1365. break;
  1366. case AzoGroupEnum:
  1367. OpName = "AzGroupEnum";
  1368. WinStatus = AzGroupEnum(
  1369. *Operation->InputHandle,
  1370. 0, // reserved
  1371. &EnumerationContext,
  1372. Operation->OutputHandle );
  1373. break;
  1374. case AzoGroupGetProp:
  1375. OpName = "AzGroupGetProperty";
  1376. WinStatus = AzGroupGetProperty(
  1377. *Operation->InputHandle,
  1378. PropertyId,
  1379. 0, // reserved
  1380. &PropertyValue );
  1381. WasGetProperty = TRUE;
  1382. if ( PropertyId == AZ_PROP_GROUP_TYPE ) {
  1383. PropType = PT_ULONG;
  1384. } else if ( PropertyId == AZ_PROP_GROUP_APP_MEMBERS ||
  1385. PropertyId == AZ_PROP_GROUP_APP_NON_MEMBERS ) {
  1386. PropType = PT_STRING_ARRAY;
  1387. } else if ( PropertyId == AZ_PROP_GROUP_LDAP_QUERY ) {
  1388. PropType = PT_LPWSTR;
  1389. } else if ( PropertyId == AZ_PROP_GROUP_MEMBERS ||
  1390. PropertyId == AZ_PROP_GROUP_NON_MEMBERS ) {
  1391. PropType = PT_SID_ARRAY;
  1392. }
  1393. break;
  1394. case AzoGroupSetProp:
  1395. OpName = "AzGroupSetProperty";
  1396. WinStatus = AzGroupSetProperty(
  1397. *Operation->InputHandle,
  1398. PropertyId,
  1399. 0, // reserved
  1400. Operation->Parameter1 );
  1401. WasSetProperty = TRUE;
  1402. if ( PropertyId == AZ_PROP_GROUP_TYPE ) {
  1403. PropType = PT_ULONG;
  1404. } else if ( PropertyId == AZ_PROP_GROUP_APP_MEMBERS ||
  1405. PropertyId == AZ_PROP_GROUP_APP_NON_MEMBERS ) {
  1406. PropType = PT_STRING_ARRAY;
  1407. } else if ( PropertyId == AZ_PROP_GROUP_LDAP_QUERY ) {
  1408. PropType = PT_LPWSTR;
  1409. } else if ( PropertyId == AZ_PROP_GROUP_MEMBERS ||
  1410. PropertyId == AZ_PROP_GROUP_NON_MEMBERS ) {
  1411. PropType = PT_SID_ARRAY;
  1412. }
  1413. SubmitHandle = *Operation->InputHandle;
  1414. break;
  1415. case AzoGroupAddProp:
  1416. OpName = "AzGroupAddProperty";
  1417. WinStatus = AzGroupAddPropertyItem(
  1418. *Operation->InputHandle,
  1419. PropertyId,
  1420. 0, // reserved
  1421. Operation->Parameter1 );
  1422. SubmitHandle = *Operation->InputHandle;
  1423. break;
  1424. case AzoGroupRemProp:
  1425. OpName = "AzGroupRemProperty";
  1426. WinStatus = AzGroupRemovePropertyItem(
  1427. *Operation->InputHandle,
  1428. PropertyId,
  1429. 0, // reserved
  1430. Operation->Parameter1 );
  1431. SubmitHandle = *Operation->InputHandle;
  1432. break;
  1433. case AzoGroupDelete:
  1434. OpName = "AzGroupDelete";
  1435. WinStatus = AzGroupDelete(
  1436. *Operation->InputHandle,
  1437. Operation->Parameter1,
  1438. 0 ); // reserved
  1439. break;
  1440. //
  1441. // Role APIs
  1442. //
  1443. case AzoRoleCreate:
  1444. OpName = "AzRoleCreate";
  1445. WinStatus = AzRoleCreate(
  1446. *Operation->InputHandle,
  1447. Operation->Parameter1,
  1448. 0, // reserved
  1449. Operation->OutputHandle );
  1450. SubmitHandle = *Operation->OutputHandle;
  1451. break;
  1452. case AzoRoleOpen:
  1453. OpName = "AzRoleOpen";
  1454. WinStatus = AzRoleOpen(
  1455. *Operation->InputHandle,
  1456. Operation->Parameter1,
  1457. 0, // reserved
  1458. Operation->OutputHandle );
  1459. break;
  1460. case AzoRoleEnum:
  1461. OpName = "AzRoleEnum";
  1462. WinStatus = AzRoleEnum(
  1463. *Operation->InputHandle,
  1464. 0, // reserved
  1465. &EnumerationContext,
  1466. Operation->OutputHandle );
  1467. break;
  1468. case AzoRoleGetProp:
  1469. OpName = "AzRoleGetProperty";
  1470. WinStatus = AzRoleGetProperty(
  1471. *Operation->InputHandle,
  1472. PropertyId,
  1473. 0, // reserved
  1474. &PropertyValue );
  1475. WasGetProperty = TRUE;
  1476. if ( PropertyId == AZ_PROP_ROLE_APP_MEMBERS ||
  1477. PropertyId == AZ_PROP_ROLE_OPERATIONS ||
  1478. PropertyId == AZ_PROP_ROLE_SCOPES ) {
  1479. PropType = PT_STRING_ARRAY;
  1480. } else if ( PropertyId == AZ_PROP_ROLE_MEMBERS ) {
  1481. PropType = PT_SID_ARRAY;
  1482. }
  1483. break;
  1484. case AzoRoleSetProp:
  1485. OpName = "AzRoleSetProperty";
  1486. WinStatus = AzRoleSetProperty(
  1487. *Operation->InputHandle,
  1488. PropertyId,
  1489. 0, // reserved
  1490. Operation->Parameter1 );
  1491. WasSetProperty = TRUE;
  1492. if ( PropertyId == AZ_PROP_ROLE_APP_MEMBERS ||
  1493. PropertyId == AZ_PROP_ROLE_OPERATIONS ||
  1494. PropertyId == AZ_PROP_ROLE_SCOPES ) {
  1495. PropType = PT_STRING_ARRAY;
  1496. } else if ( PropertyId == AZ_PROP_ROLE_MEMBERS ) {
  1497. PropType = PT_SID_ARRAY;
  1498. }
  1499. SubmitHandle = *Operation->InputHandle;
  1500. break;
  1501. case AzoRoleAddProp:
  1502. OpName = "AzRoleAddProperty";
  1503. WinStatus = AzRoleAddPropertyItem(
  1504. *Operation->InputHandle,
  1505. PropertyId,
  1506. 0, // reserved
  1507. Operation->Parameter1 );
  1508. SubmitHandle = *Operation->InputHandle;
  1509. break;
  1510. case AzoRoleRemProp:
  1511. OpName = "AzRoleRemProperty";
  1512. WinStatus = AzRoleRemovePropertyItem(
  1513. *Operation->InputHandle,
  1514. PropertyId,
  1515. 0, // reserved
  1516. Operation->Parameter1 );
  1517. SubmitHandle = *Operation->InputHandle;
  1518. break;
  1519. case AzoRoleDelete:
  1520. OpName = "AzRoleDelete";
  1521. WinStatus = AzRoleDelete(
  1522. *Operation->InputHandle,
  1523. Operation->Parameter1,
  1524. 0 ); // reserved
  1525. break;
  1526. //
  1527. // JunctionPoint APIs
  1528. //
  1529. case AzoJPCreate:
  1530. OpName = "AzJunctionPointCreate";
  1531. WinStatus = AzJunctionPointCreate(
  1532. *Operation->InputHandle,
  1533. Operation->Parameter1,
  1534. 0, // reserved
  1535. Operation->OutputHandle );
  1536. SubmitHandle = *Operation->OutputHandle;
  1537. break;
  1538. case AzoJPOpen:
  1539. OpName = "AzJunctionPointOpen";
  1540. WinStatus = AzJunctionPointOpen(
  1541. *Operation->InputHandle,
  1542. Operation->Parameter1,
  1543. 0, // reserved
  1544. Operation->OutputHandle );
  1545. break;
  1546. case AzoJPEnum:
  1547. OpName = "AzJunctionPointEnum";
  1548. WinStatus = AzJunctionPointEnum(
  1549. *Operation->InputHandle,
  1550. 0, // reserved
  1551. &EnumerationContext,
  1552. Operation->OutputHandle );
  1553. break;
  1554. case AzoJPGetProp:
  1555. OpName = "AzJunctionPointGetProperty";
  1556. WinStatus = AzJunctionPointGetProperty(
  1557. *Operation->InputHandle,
  1558. PropertyId,
  1559. 0, // reserved
  1560. &PropertyValue );
  1561. WasGetProperty = TRUE;
  1562. if ( PropertyId == AZ_PROP_JUNCTION_POINT_APPLICATION ) {
  1563. PropType = PT_LPWSTR;
  1564. }
  1565. break;
  1566. case AzoJPSetProp:
  1567. OpName = "AzJunctionPointSetProperty";
  1568. WinStatus = AzJunctionPointSetProperty(
  1569. *Operation->InputHandle,
  1570. PropertyId,
  1571. 0, // reserved
  1572. Operation->Parameter1 );
  1573. WasSetProperty = TRUE;
  1574. if ( PropertyId == AZ_PROP_JUNCTION_POINT_APPLICATION ) {
  1575. PropType = PT_LPWSTR;
  1576. }
  1577. SubmitHandle = *Operation->InputHandle;
  1578. break;
  1579. case AzoJPDelete:
  1580. OpName = "AzJunctionPointDelete";
  1581. WinStatus = AzJunctionPointDelete(
  1582. *Operation->InputHandle,
  1583. Operation->Parameter1,
  1584. 0 ); // reserved
  1585. break;
  1586. case AzoClose:
  1587. OpName = "AzCloseHandle";
  1588. WinStatus = AzCloseHandle(
  1589. *Operation->InputHandle,
  1590. 0 ); // reserved
  1591. break;
  1592. // Pseudo function test links between objects
  1593. case AzoTestLink:
  1594. OpName = "TestLink";
  1595. // Handle to the parent of the object being linked from
  1596. TestLinkHandleP = *Operation->InputHandle;
  1597. // Handle to the object being linked from
  1598. TestLinkHandleA = *Operation->OutputHandle;
  1599. // PropId to use for all set/get property
  1600. TestLinkPropId = PropertyId;
  1601. // Opcode offset to use for linked-to objects
  1602. TestLinkOpcodeOffset = Operation->ExpectedStatus;
  1603. // Name of the object being linked from
  1604. wcscpy(TestLinkObjectName, Operation->ExpectedParameter1);
  1605. WinStatus = Operation->ExpectedStatus;
  1606. //
  1607. // Build a new echo prefix
  1608. //
  1609. strcpy( BigBuffer, EchoPrefix );
  1610. strcat( BigBuffer, "->" );
  1611. strcat( BigBuffer, (LPSTR)Operation->Parameter1 );
  1612. //
  1613. // Print a description of the operation
  1614. //
  1615. PrintIndent( Indentation, FALSE );
  1616. printf( "\n%s - Test linking '%s' objects to the object named '%ws' using propid '%ld'.\n",
  1617. BigBuffer,
  1618. Operation->Parameter1,
  1619. TestLinkObjectName,
  1620. TestLinkPropId );
  1621. break;
  1622. // Pseudo function to duplicate a handle
  1623. case AzoDupHandle:
  1624. OpName = "DupHandle";
  1625. *Operation->OutputHandle = *Operation->InputHandle;
  1626. WinStatus = NO_ERROR;
  1627. break;
  1628. // Pseudo function to execute a "subroutine" of operations
  1629. case AzoGoSub:
  1630. OpName = "GoSub";
  1631. WinStatus = NO_ERROR;
  1632. break;
  1633. // Pseudo function to echo text to stdout
  1634. case AzoEcho:
  1635. OpName = BigBuffer;
  1636. strcpy( OpName, "\n");
  1637. if ( EchoPrefix ) {
  1638. strcat( OpName, EchoPrefix );
  1639. strcat( OpName, " -" );
  1640. }
  1641. WinStatus = NO_ERROR;
  1642. break;
  1643. default:
  1644. OpName = "<Unknown>";
  1645. PrintIndent( Indentation+4, TRUE );
  1646. RetVal = FALSE;
  1647. printf( "Need to fix test app to handle a new opcode: %ld\n", Opcode );
  1648. WinStatus = Operation->ExpectedStatus;
  1649. break;
  1650. }
  1651. //
  1652. // Print the operation
  1653. //
  1654. if ( FirstIteration ) {
  1655. if ( Opcode != AzoTestLink ) {
  1656. PrintIndent( Indentation, FALSE );
  1657. printf( "%s ", OpName );
  1658. if ( Operation->Parameter1 != NULL ) {
  1659. if ( WasSetProperty ) {
  1660. switch ( PropType ) {
  1661. case PT_LPWSTR:
  1662. printf( "'%ws' ", Operation->Parameter1 );
  1663. break;
  1664. case PT_ULONG:
  1665. printf( "'%ld' ", *(PULONG)Operation->Parameter1 );
  1666. break;
  1667. }
  1668. } else {
  1669. printf( "'%ws' ", Operation->Parameter1 );
  1670. }
  1671. }
  1672. if ( PropertyId != 0 ) {
  1673. printf( "(%ld) ", PropertyId );
  1674. }
  1675. if ( Operation->ExpectedStatus != NO_ERROR ) {
  1676. printf("(");
  1677. PrintStatus( Operation->ExpectedStatus );
  1678. printf(") ");
  1679. }
  1680. printf( "\n" );
  1681. }
  1682. }
  1683. FirstIteration = FALSE;
  1684. //
  1685. // Handle ERROR_NO_MORE_ITEMS/NO_ERROR mapping
  1686. //
  1687. RealWinStatus = WinStatus;
  1688. if ( Operation->EnumOperations != NULL ) {
  1689. if ( WinStatus == ERROR_NO_MORE_ITEMS ) {
  1690. WinStatus = NO_ERROR;
  1691. }
  1692. }
  1693. //
  1694. // Ensure we got the right status code
  1695. //
  1696. if ( WinStatus != Operation->ExpectedStatus ) {
  1697. PrintIndent( Indentation+4, TRUE );
  1698. RetVal = FALSE;
  1699. printf( "Returned '" );
  1700. PrintStatus( WinStatus );
  1701. printf( "' instead of '");
  1702. PrintStatus( Operation->ExpectedStatus );
  1703. printf( "'");
  1704. printf( "\n" );
  1705. break;
  1706. }
  1707. //
  1708. // Do GetProperty specific code
  1709. //
  1710. if ( WasGetProperty ) {
  1711. //
  1712. // Print the property
  1713. //
  1714. switch ( PropType ) {
  1715. case PT_LPWSTR:
  1716. if ( PropertyValue == NULL ) {
  1717. PrintIndent( Indentation+4, TRUE );
  1718. RetVal = FALSE;
  1719. printf( "<NULL>\n", PropertyValue );
  1720. } else {
  1721. PrintIndent( Indentation+4, FALSE );
  1722. printf( "'%ws'\n", PropertyValue );
  1723. }
  1724. //
  1725. // Check if that value is expected
  1726. //
  1727. if ( Operation->ExpectedParameter1 != NULL &&
  1728. wcscmp( Operation->ExpectedParameter1, PropertyValue) != 0 ) {
  1729. PrintIndent( Indentation+4, TRUE );
  1730. RetVal = FALSE;
  1731. printf( "Expected '%ws' instead of '%ws'\n", Operation->ExpectedParameter1, PropertyValue );
  1732. }
  1733. break;
  1734. case PT_STRING_ARRAY:
  1735. StringArray1 = (PAZ_STRING_ARRAY) PropertyValue;;
  1736. if ( PropertyValue == NULL ) {
  1737. PrintIndent( Indentation+4, TRUE );
  1738. RetVal = FALSE;
  1739. printf( "<NULL>\n", PropertyValue );
  1740. } else {
  1741. for ( i=0; i<StringArray1->StringCount; i++ ) {
  1742. PrintIndent( Indentation+4, FALSE );
  1743. printf( "'%ws'\n", StringArray1->Strings[i] );
  1744. }
  1745. }
  1746. //
  1747. // Check if that value is expected
  1748. //
  1749. if ( Operation->ExpectedParameter1 != NULL ) {
  1750. StringArray2 = (PAZ_STRING_ARRAY)Operation->ExpectedParameter1;
  1751. if ( StringArray1->StringCount != StringArray2->StringCount ) {
  1752. PrintIndent( Indentation+4, TRUE );
  1753. RetVal = FALSE;
  1754. printf( "Expected '%ld' strings instead of '%ld' strings\n", StringArray2->StringCount, StringArray1->StringCount );
  1755. } else {
  1756. for ( i=0; i<StringArray1->StringCount; i++ ) {
  1757. if ( wcscmp( StringArray1->Strings[i], StringArray2->Strings[i]) != 0 ) {
  1758. PrintIndent( Indentation+4, TRUE );
  1759. RetVal = FALSE;
  1760. printf( "Expected string %ld to be '%ws' instead of '%ws'\n",
  1761. i,
  1762. StringArray2->Strings[i],
  1763. StringArray1->Strings[i] );
  1764. }
  1765. }
  1766. }
  1767. }
  1768. break;
  1769. case PT_ULONG:
  1770. if ( PropertyValue == NULL ) {
  1771. PrintIndent( Indentation+4, TRUE );
  1772. RetVal = FALSE;
  1773. printf( "<NULL>\n", PropertyValue );
  1774. } else {
  1775. PrintIndent( Indentation+4, FALSE );
  1776. printf( "'%ld'\n", *(PULONG)PropertyValue );
  1777. }
  1778. //
  1779. // Check if that value is expected
  1780. //
  1781. if ( *(PULONG)(Operation->ExpectedParameter1) != *(PULONG)PropertyValue ) {
  1782. PrintIndent( Indentation+4, TRUE );
  1783. RetVal = FALSE;
  1784. printf( "Expected '%ld' instead of '%ld'\n",
  1785. *(PULONG)(Operation->ExpectedParameter1),
  1786. *(PULONG)PropertyValue );
  1787. }
  1788. break;
  1789. case PT_SID_ARRAY:
  1790. SidArray1 = (PAZ_SID_ARRAY) PropertyValue;;
  1791. if ( PropertyValue == NULL ) {
  1792. PrintIndent( Indentation+4, TRUE );
  1793. RetVal = FALSE;
  1794. printf( "<NULL>\n" );
  1795. } else {
  1796. LPWSTR TempString;
  1797. for ( i=0; i<SidArray1->SidCount; i++ ) {
  1798. PrintIndent( Indentation+4, FALSE );
  1799. if ( !ConvertSidToStringSidW( SidArray1->Sids[i],
  1800. &TempString ) ) {
  1801. PrintIndent( Indentation+4, TRUE );
  1802. RetVal = FALSE;
  1803. printf( "Cannot convert sid.\n" );
  1804. } else {
  1805. printf( "'%ws'\n", TempString );
  1806. }
  1807. }
  1808. }
  1809. //
  1810. // Check if that value is expected
  1811. //
  1812. if ( Operation->ExpectedParameter1 != NULL ) {
  1813. SidArray2 = (PAZ_SID_ARRAY)Operation->ExpectedParameter1;
  1814. if ( SidArray1->SidCount != SidArray2->SidCount ) {
  1815. PrintIndent( Indentation+4, TRUE );
  1816. RetVal = FALSE;
  1817. printf( "Expected '%ld' sids instead of '%ld' sids\n", SidArray2->SidCount, SidArray1->SidCount );
  1818. } else {
  1819. for ( i=0; i<SidArray1->SidCount; i++ ) {
  1820. if ( !EqualSid( SidArray1->Sids[i], SidArray2->Sids[i]) ) {
  1821. LPWSTR TempString1;
  1822. LPWSTR TempString2;
  1823. if ( !ConvertSidToStringSidW( SidArray1->Sids[i],
  1824. &TempString1 ) ) {
  1825. PrintIndent( Indentation+4, TRUE );
  1826. RetVal = FALSE;
  1827. printf( "Cannot convert sid.\n" );
  1828. continue;
  1829. }
  1830. if ( !ConvertSidToStringSidW( SidArray2->Sids[i],
  1831. &TempString2 ) ) {
  1832. PrintIndent( Indentation+4, TRUE );
  1833. RetVal = FALSE;
  1834. printf( "Cannot convert sid.\n" );
  1835. continue;
  1836. }
  1837. PrintIndent( Indentation+4, TRUE );
  1838. RetVal = FALSE;
  1839. printf( "Expected string %ld to be '%ws' instead of '%ws'\n",
  1840. i,
  1841. TempString2,
  1842. TempString1 );
  1843. }
  1844. }
  1845. }
  1846. }
  1847. break;
  1848. default:
  1849. ASSERT(FALSE);
  1850. }
  1851. //
  1852. // Free the returned buffer
  1853. //
  1854. AzFreeMemory( PropertyValue );
  1855. }
  1856. //
  1857. // Submit the changes to the database
  1858. //
  1859. if ( WinStatus == NO_ERROR && SubmitHandle != INVALID_HANDLE_VALUE ) {
  1860. WinStatus = AzSubmit( SubmitHandle,
  1861. 0); // reserved
  1862. if ( WinStatus != NO_ERROR ) {
  1863. PrintIndent( Indentation+4, TRUE );
  1864. RetVal = FALSE;
  1865. printf( "AzSubmit failed %ld\n", WinStatus );
  1866. }
  1867. }
  1868. //
  1869. // Execute a "subroutine" of operations
  1870. //
  1871. if ( Opcode == AzoGoSub ) {
  1872. if (!DoOperations( Operation->EnumOperations, Indentation + 4, SpecificOpcodeOffset, EchoPrefix ) ) {
  1873. RetVal = FALSE;
  1874. }
  1875. //
  1876. // Execute a the special TestLink "subroutine" of operations
  1877. //
  1878. } else if ( Opcode == AzoTestLink ) {
  1879. if (!DoOperations( Operation->EnumOperations, Indentation + 4, SpecificOpcodeOffset, BigBuffer ) ) {
  1880. RetVal = FALSE;
  1881. }
  1882. TestLinkPropId = 0;
  1883. //
  1884. // Do enumeration specific code
  1885. //
  1886. } else if ( Operation->EnumOperations != NULL && RealWinStatus == NO_ERROR ) {
  1887. PrintIndent( Indentation+4, FALSE );
  1888. printf( "%ld:\n", EnumerationContext );
  1889. if (!DoOperations( Operation->EnumOperations, Indentation + 8, SpecificOpcodeOffset, EchoPrefix ) ) {
  1890. RetVal = FALSE;
  1891. break;
  1892. }
  1893. continue;
  1894. }
  1895. //
  1896. // Do the next operation
  1897. //
  1898. EnumerationContext = 0;
  1899. FirstIteration = TRUE;
  1900. Operation++;
  1901. }
  1902. return RetVal;
  1903. }
  1904. int __cdecl
  1905. main(
  1906. IN int argc,
  1907. IN char ** argv
  1908. )
  1909. /*++
  1910. Routine Description:
  1911. Test azroles.dll
  1912. Arguments:
  1913. argc - the number of command-line arguments.
  1914. argv - an array of pointers to the arguments.
  1915. Return Value:
  1916. Exit status
  1917. --*/
  1918. {
  1919. BOOL RetVal = TRUE;
  1920. ULONG TestNum;
  1921. ULONG Index;
  1922. ULONG Index2;
  1923. CHAR EchoPrefix[1024];
  1924. //
  1925. // Objects that are children of "AdminManager"
  1926. //
  1927. DWORD GenAdmChildTests[] = { AzoApp, AzoGroup };
  1928. LPSTR GenAdmChildTestName[] = { "Application", "Group" };
  1929. POPERATION SpeAdmChildTestOps[] = { NULL, OpAdmGroup };
  1930. POPERATION GenAdmChildTestOps[] = { OpAdmChildGen, OpAdmChildGenDupName
  1931. #ifdef ENABLE_LEAK
  1932. , OpAdmChildGenLeak
  1933. #endif // ENABLE_LEAK
  1934. };
  1935. //
  1936. // Objects that are children of "Application"
  1937. //
  1938. DWORD GenAppChildTests[] = { AzoOp, AzoTask, AzoScope, AzoGroup, AzoRole, AzoJP };
  1939. LPSTR GenAppChildTestName[] = { "Operation", "Task", "Scope", "Group", "Role", "JunctionPoint" };
  1940. POPERATION SpeAppChildTestOps[] = { OpOperation, OpTask, NULL, OpAppGroup, OpAppRole, OpAppJunctionPoint };
  1941. POPERATION GenAppChildTestOps[] = { OpAppChildGen, OpAppChildGenHandleOpen, OpAppChildGenDupName };
  1942. //
  1943. // Objects that are children of "Scope"
  1944. //
  1945. DWORD GenScopeChildTests[] = { AzoGroup, AzoRole };
  1946. LPSTR GenScopeChildTestName[] = { "Group", "Role" };
  1947. POPERATION SpeScopeChildTestOps[] = { OpScopeGroup, OpScopeRole };
  1948. POPERATION GenScopeChildTestOps[] = { OpScopeChildGen, OpScopeChildGenDupName };
  1949. struct {
  1950. //
  1951. // Name of the parent object
  1952. LPSTR ParentName;
  1953. //
  1954. // List of children to test for this parent
  1955. DWORD ChildCount;
  1956. DWORD *ChildOpcodeOffsets;
  1957. LPSTR *ChildTestNames;
  1958. // Operation to perform that is specific to the child type
  1959. POPERATION *ChildOperations;
  1960. //
  1961. // List of tests to perform for each child type
  1962. //
  1963. DWORD OperationCount;
  1964. POPERATION *Operations;
  1965. } ParentChildTests[] = {
  1966. { "AdminManager",
  1967. sizeof(GenAdmChildTestName)/sizeof(GenAdmChildTestName[0]),
  1968. GenAdmChildTests,
  1969. GenAdmChildTestName,
  1970. SpeAdmChildTestOps,
  1971. sizeof(GenAdmChildTestOps)/sizeof(GenAdmChildTestOps[0]),
  1972. GenAdmChildTestOps },
  1973. { "Application",
  1974. sizeof(GenAppChildTestName)/sizeof(GenAppChildTestName[0]),
  1975. GenAppChildTests,
  1976. GenAppChildTestName,
  1977. SpeAppChildTestOps,
  1978. sizeof(GenAppChildTestOps)/sizeof(GenAppChildTestOps[0]),
  1979. GenAppChildTestOps },
  1980. { "Scope",
  1981. sizeof(GenScopeChildTestName)/sizeof(GenScopeChildTestName[0]),
  1982. GenScopeChildTests,
  1983. GenScopeChildTestName,
  1984. SpeScopeChildTestOps,
  1985. sizeof(GenScopeChildTestOps)/sizeof(GenScopeChildTestOps[0]),
  1986. GenScopeChildTestOps },
  1987. };
  1988. // Delete the testfile
  1989. DeleteFileA( ".\\TestFile" );
  1990. // #if 0
  1991. //
  1992. // Loop for each object that can be the parent of another object
  1993. //
  1994. for ( TestNum=0; TestNum < sizeof(ParentChildTests)/sizeof(ParentChildTests[0]); TestNum++ ) {
  1995. //
  1996. // Loop for each child of the parent object
  1997. //
  1998. for ( Index=0; Index < ParentChildTests[TestNum].ChildCount; Index ++ ) {
  1999. //
  2000. // output the test name
  2001. //
  2002. strcpy( EchoPrefix, ParentChildTests[TestNum].ParentName );
  2003. strcat( EchoPrefix, "->" );
  2004. strcat( EchoPrefix, ParentChildTests[TestNum].ChildTestNames[Index] );
  2005. printf("\n%s - Perform tests of '%s' objects that are children of '%s' objects\n",
  2006. EchoPrefix,
  2007. ParentChildTests[TestNum].ChildTestNames[Index],
  2008. ParentChildTests[TestNum].ParentName );
  2009. //
  2010. // Do the various generic tests that apply to all objects
  2011. //
  2012. for ( Index2=0; Index2 < ParentChildTests[TestNum].OperationCount; Index2 ++ ) {
  2013. if ( !DoOperations(
  2014. ParentChildTests[TestNum].Operations[Index2],
  2015. 0,
  2016. ParentChildTests[TestNum].ChildOpcodeOffsets[Index],
  2017. EchoPrefix ) ) {
  2018. RetVal = FALSE;
  2019. goto Cleanup;
  2020. }
  2021. // Delete the testfile
  2022. if ( !DeleteFileA( ".\\TestFile" )) {
  2023. printf( "Cannot delete TestFile %ld\n", GetLastError() );
  2024. RetVal = FALSE;
  2025. goto Cleanup;
  2026. }
  2027. }
  2028. //
  2029. // Do the one test that is specific to this parent/child relationship
  2030. //
  2031. if ( ParentChildTests[TestNum].ChildOperations[Index] == NULL ) {
  2032. // ??? Should complain here. Test is missing
  2033. } else {
  2034. if ( !DoOperations(
  2035. ParentChildTests[TestNum].ChildOperations[Index],
  2036. 0,
  2037. ParentChildTests[TestNum].ChildOpcodeOffsets[Index],
  2038. EchoPrefix ) ) {
  2039. RetVal = FALSE;
  2040. goto Cleanup;
  2041. }
  2042. // Delete the testfile
  2043. if ( !DeleteFileA( ".\\TestFile" )) {
  2044. printf( "Cannot delete TestFile %ld\n", GetLastError() );
  2045. RetVal = FALSE;
  2046. goto Cleanup;
  2047. }
  2048. }
  2049. }
  2050. }
  2051. //
  2052. // Do name sharing specific tests
  2053. //
  2054. if ( !DoOperations( OpShare, 0, 0, "NameShare" ) ) {
  2055. RetVal = FALSE;
  2056. goto Cleanup;
  2057. }
  2058. // Delete the testfile
  2059. if ( !DeleteFileA( ".\\TestFile" )) {
  2060. printf( "Cannot delete TestFile %ld\n", GetLastError() );
  2061. RetVal = FALSE;
  2062. goto Cleanup;
  2063. }
  2064. // #endif // 0
  2065. //
  2066. // Do peristence specific tests
  2067. //
  2068. if ( !DoOperations( OpPersist, 0, 0, "Persist" ) ) {
  2069. RetVal = FALSE;
  2070. goto Cleanup;
  2071. }
  2072. // Delete the testfile
  2073. if ( !DeleteFileA( ".\\TestFile" )) {
  2074. printf( "Cannot delete TestFile %ld\n", GetLastError() );
  2075. RetVal = FALSE;
  2076. goto Cleanup;
  2077. }
  2078. //
  2079. // Check for memory leaks
  2080. //
  2081. if ( RetVal ) {
  2082. AzpUnload();
  2083. }
  2084. //
  2085. // Done
  2086. //
  2087. Cleanup:
  2088. printf( "\n\n" );
  2089. if ( RetVal ) {
  2090. printf( "Tests completed successfully!\n");
  2091. return 0;
  2092. } else {
  2093. printf( "One or more tests failed.\n");
  2094. return 1;
  2095. }
  2096. }