xref: /illumos-gate/usr/src/lib/libima/common/ima-lib.c (revision 3d393ee6c37fa10ac512ed6d36109ad616dc7c1a)
1 /*
2  * Description
3  * ImaLib.c - Implements a sample common IMA library
4  *
5  * License:
6  * The contents of this file are subject to the SNIA Public License
7  * Version 1.0(the "License"); you may not use this file except in
8  *  compliance with the License. You may obtain a copy of the License at
9  *
10  * /http://www.snia.org/English/Resources/Code/OpenSource.html
11  *
12  *  Software distributed under the License is distributed on an "AS IS"
13  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14  *  the License for the specific language governing rights and limitations
15  *  under the License.
16  *
17  * The Original Code is  SNIA HBA API and IMA general header file
18  *
19  * The Initial Developer of the Original Code is:
20  * Benjamin F. Kuo, Troika Networks, Inc. (benk@troikanetworks.com)
21  * David Dillard       VERITAS Software        david.dillard@veritas.com
22  *
23  * Contributor(s):
24  * Jeff Ding, Adaptec, Inc. (jding@corp.adaptec.com)
25  *
26  *   Changes:
27  *  09/24/2003 Initial Draft
28  *  (for other changes... see the CVS logs)
29  *
30  *  12/15/2003 corrected the defined parameter in IMA_SetPhbaIsnsDiscovery().
31  *  lower case the computer name as iscsi name in IMA_GenerateNodeName().
32  *
33  *  01/21/2005 Updated to support IMA 1.1.3.
34  */
35 
36 #ifdef WIN32
37 #include <windows.h>
38 #else
39 #define	_XOPEN_SOURCE /* glibc2 needs this */
40 #include <sys/sem.h>
41 #include <dlfcn.h>
42 #include <stdarg.h>
43 #endif
44 
45 #include <string.h>
46 #include <stdlib.h>
47 // #include <sys/sem.h>
48 // #include <unistd.h>
49 #include <time.h>
50 #include <stdio.h>
51 #include <sys/types.h>
52 // #include <sys/ipc.h>
53 
54 #include "ima.h"
55 #include "ima-plugin.h"
56 
57 
58 #define	LIBRARY_PROPERTY_SUPPORTED_IMA_VERSION 1
59 #define	LIBRARY_PROPERTY_IMPLEMENTATION_VERSION L"1.0.2"
60 #define	LIBRARY_PROPERTY_VENDOR L"QLogic, Inc."
61 #define	DEFAULT_NODE_NAME_FORMAT "iqn.1986-03.com.sun.central.%s"
62 
63 /* Linux only */
64 #define	LIBRARY_FILE_NAME L"libima.so"
65 
66 #define	IMA_MAX_NUM_PLUGINS 32
67 #define	IMA_MAX_CALLBACK_PER_PLUGIN 64
68 
69 #define	EUOS_ERROR IMA_ERROR_UNEXPECTED_OS_ERROR
70 
71 typedef struct ima_plugin_info {
72 	char PluginName[64];
73 	char PluginPath[256];
74 #ifdef WIN32
75 	HINSTANCE hPlugin; /* Handle to a loaded DLL */
76 #else
77 	void* hPlugin; /* Handle to a loaded DLL */
78 #endif
79 	IMA_UINT32 ownerId;
80 #ifdef WIN32
81 	HANDLE pluginMutex;
82 #else
83 	int pluginMutex;
84 #endif
85 	IMA_UINT number_of_vbcallbacks;
86 	IMA_OBJECT_VISIBILITY_FN vbcallback[IMA_MAX_CALLBACK_PER_PLUGIN];
87 	IMA_UINT number_of_pccallbacks;
88 	IMA_OBJECT_PROPERTY_FN pccallback[IMA_MAX_CALLBACK_PER_PLUGIN];
89 } IMA_PLUGIN_INFO, *PIMA_PLUGIN_INFO;
90 
91 static IMA_PLUGIN_INFO  plugintable[IMA_MAX_NUM_PLUGINS];
92 static int number_of_plugins = -1;
93 static IMA_NODE_NAME    sharedNodeName;
94 static IMA_NODE_ALIAS   sharedNodeAlias;
95 
96 #ifdef WIN32
97 static HANDLE libMutex = NULL;
98 #else
99 static int libMutex = -1;
100 #endif
101 
102 void InitLibrary();
103 void ExitLibrary();
104 
105 static void libSwprintf(wchar_t *wcs, const wchar_t *lpszFormat, ...) {
106 	va_list args;
107 	va_start(args, lpszFormat);
108 
109 #ifdef WIN32
110 	vswprintf(wcs, lpszFormat, args);
111 #else
112 	vswprintf(wcs, 255, lpszFormat, args);
113 #endif
114 	va_end(args);
115 }
116 
117 
118 #ifdef WIN32
119 /* Begin implementation */
120 BOOL APIENTRY DllMain(HANDLE hModule,
121     DWORD  ul_reason_for_call,
122     LPVOID lpReserved) {
123 	switch (ul_reason_for_call) {
124 
125 	case DLL_PROCESS_ATTACH:
126 		// InitLibrary();
127 		break;
128 	case DLL_PROCESS_DETACH:
129 		ExitLibrary();
130 		break;
131 	case DLL_THREAD_ATTACH:
132 	case DLL_THREAD_DETACH:
133 		break;
134 	}
135 	return (TRUE);
136 }
137 #elif defined(SOLARIS)
138 
139 void so_init(void);
140 void so_fini(void);
141 static int os_createmutex(int *semid);
142 static void os_obtainmutex(int semid);
143 static void os_releasemutex(int semid);
144 static void os_destroymutex(int semid);
145 static IMA_STATUS getSolarisNodeProps(IMA_NODE_PROPERTIES *nodeProps);
146 static IMA_STATUS getSolarisSharedNodeName(IMA_NODE_NAME name);
147 static IMA_STATUS getSolarisSharedNodeAlias(IMA_NODE_ALIAS alias);
148 static IMA_STATUS setSolarisSharedNodeName(const IMA_NODE_NAME name);
149 static IMA_STATUS setSolarisSharedNodeAlias(const IMA_NODE_ALIAS alias);
150 
151 #pragma init(so_init)
152 #pragma fini(so_fini)
153 
154 void so_init() {
155 	InitLibrary();
156 }
157 void so_fini() {
158 	ExitLibrary();
159 }
160 
161 static IMA_STATUS getSolarisNodeProps(IMA_NODE_PROPERTIES *nodeProps) {
162 	int ret;
163 	int i;
164 	IMA_STATUS status = IMA_ERROR_UNKNOWN_ERROR;
165 	IMA_GetNodePropertiesFn PassFunc;
166 	IMA_OID nodeOid;
167 
168 	if (number_of_plugins == -1)
169 		InitLibrary();
170 
171 	/*
172 	 * See if iscsiadm and ima plugin packages have been installed.
173 	 */
174 	ret = system("pkginfo SUNWima > /dev/null");
175 	if (ret) {
176 		return (status);
177 	}
178 
179 	ret = system("pkginfo SUNWiscsir > /dev/null");
180 	if (ret) {
181 		return (status);
182 	}
183 
184 	os_obtainmutex(libMutex);
185 	status = IMA_ERROR_OBJECT_NOT_FOUND;
186 
187 	for (i = 0; i < number_of_plugins; i++) {
188 		if (strstr(plugintable[i].PluginPath,
189 		    "libsun_ima.so") == NULL) {
190 			continue;
191 		}
192 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
193 		if (plugintable[i].hPlugin != NULL) {
194 			os_obtainmutex(plugintable[i].pluginMutex);
195 			PassFunc =
196 			    (IMA_GetNodePropertiesFn) dlsym(
197 			    plugintable[i].hPlugin,
198 			    "IMA_GetNodeProperties");
199 			if (PassFunc != NULL) {
200 				status = PassFunc(nodeOid, nodeProps);
201 			}
202 			os_releasemutex(plugintable[i].pluginMutex);
203 		}
204 		break;
205 	}
206 
207 	os_releasemutex(libMutex);
208 	return (status);
209 }
210 
211 static IMA_STATUS getSolarisSharedNodeName(IMA_NODE_NAME name) {
212 	IMA_STATUS status = IMA_ERROR_UNKNOWN_ERROR;
213 	IMA_NODE_PROPERTIES nodeProps;
214 
215 	status = getSolarisNodeProps(&nodeProps);
216 	if (status != IMA_STATUS_SUCCESS) {
217 		return (status);
218 	}
219 	bcopy(&nodeProps.name, name, sizeof (IMA_NODE_NAME));
220 	return (status);
221 }
222 
223 static IMA_STATUS getSolarisSharedNodeAlias(IMA_NODE_ALIAS alias) {
224 	IMA_STATUS status = IMA_ERROR_UNKNOWN_ERROR;
225 	IMA_NODE_PROPERTIES nodeProps;
226 
227 	status = getSolarisNodeProps(&nodeProps);
228 	if (status != IMA_STATUS_SUCCESS) {
229 		return (status);
230 	}
231 	bcopy(&nodeProps.alias, alias, sizeof (IMA_NODE_ALIAS));
232 	return (status);
233 }
234 
235 static IMA_STATUS setSolarisSharedNodeName(const IMA_NODE_NAME name) {
236 	int ret;
237 	int i;
238 	IMA_STATUS status = IMA_ERROR_UNKNOWN_ERROR;
239 	IMA_NODE_PROPERTIES nodeProps;
240 	IMA_SetNodeNameFn PassFunc;
241 	IMA_OID nodeOid;
242 
243 	if (number_of_plugins == -1)
244 		InitLibrary();
245 
246 	/*
247 	 * See if iscsiadm and ima plugin packages have been installed.
248 	 */
249 	ret = system("pkginfo SUNWima > /dev/null");
250 	if (ret) {
251 		return (status);
252 	}
253 
254 	ret = system("pkginfo SUNWiscsir > /dev/null");
255 	if (ret) {
256 		return (status);
257 	}
258 
259 	os_obtainmutex(libMutex);
260 	status = IMA_ERROR_OBJECT_NOT_FOUND;
261 
262 	for (i = 0; i < number_of_plugins; i++) {
263 		if (strstr(plugintable[i].PluginPath,
264 		    "libsun_ima.so") == NULL) {
265 			continue;
266 		}
267 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
268 		if (plugintable[i].hPlugin != NULL) {
269 			os_obtainmutex(plugintable[i].pluginMutex);
270 			PassFunc =
271 			    (IMA_SetNodeNameFn) dlsym(plugintable[i].hPlugin,
272 			    "IMA_SetNodeName");
273 			if (PassFunc != NULL) {
274 				status = PassFunc(nodeOid, name);
275 			}
276 			os_releasemutex(plugintable[i].pluginMutex);
277 		}
278 		break;
279 	}
280 
281 	os_releasemutex(libMutex);
282 	return (status);
283 }
284 
285 static IMA_STATUS setSolarisSharedNodeAlias(const IMA_NODE_ALIAS alias) {
286 	int ret;
287 	int i;
288 	IMA_STATUS status = IMA_ERROR_UNKNOWN_ERROR;
289 	IMA_NODE_PROPERTIES nodeProps;
290 	IMA_SetNodeAliasFn PassFunc;
291 	IMA_OID nodeOid;
292 
293 	if (number_of_plugins == -1)
294 		InitLibrary();
295 
296 	/*
297 	 * See if iscsiadm and ima plugin packages have been installed.
298 	 */
299 	ret = system("pkginfo SUNWima > /dev/null");
300 	if (ret) {
301 		return (status);
302 	}
303 
304 	ret = system("pkginfo SUNWiscsir > /dev/null");
305 	if (ret) {
306 		return (status);
307 	}
308 
309 	os_obtainmutex(libMutex);
310 	status = IMA_ERROR_OBJECT_NOT_FOUND;
311 
312 	for (i = 0; i < number_of_plugins; i++) {
313 		if (strstr(plugintable[i].PluginPath,
314 		    "libsun_ima.so") == NULL) {
315 			continue;
316 		}
317 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
318 		if (plugintable[i].hPlugin != NULL) {
319 			os_obtainmutex(plugintable[i].pluginMutex);
320 			PassFunc =
321 			    (IMA_SetNodeAliasFn) dlsym(plugintable[i].hPlugin,
322 			    "IMA_SetNodeAlias");
323 			if (PassFunc != NULL) {
324 				status = PassFunc(nodeOid, alias);
325 			}
326 			os_releasemutex(plugintable[i].pluginMutex);
327 		}
328 		break;
329 	}
330 
331 	os_releasemutex(libMutex);
332 	return (status);
333 }
334 
335 #else
336 /*
337  * add code in .init and .fini,
338  * "__attribute__ ((constructor))" and "__attribute__ ((destructor))"
339  * are used with gcc
340  */
341 __attribute__ ((constructor)) void init() {
342 	InitLibrary();
343 }
344 
345 __attribute__ ((destructor)) void fini() {
346 	ExitLibrary();
347 }
348 
349 #endif
350 
351 
352 #ifdef WIN32
353 
354 static BOOL os_createmutex(HANDLE Mutex) {
355 	Mutex = CreateMutex(NULL, FALSE, NULL);
356 
357 	if (Mutex == NULL) {
358 		return (FALSE);
359 	}
360 
361 	return (TRUE);
362 }
363 
364 static void os_destroymutex(HANDLE Mutex) {
365 	if (Mutex != NULL) {
366 		CloseHandle(Mutex);
367 	}
368 }
369 
370 
371 static void os_obtainmutex(HANDLE Mutex) {
372 	WaitForSingleObject(Mutex, INFINITE);
373 }
374 
375 static void os_releasemutex(HANDLE Mutex) {
376 	ReleaseMutex(Mutex);
377 }
378 
379 #else
380 #if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
381 /* <sys/sem.h> */
382 #else
383 union semun {
384 	int val; /* value for SETVAL */
385 	struct semid_ds *bf; /* buffer for IPC_STAT, IPC_SET */
386 	unsigned short int *array; /* array for GETALL, SETALL */
387 	struct seminfo *__buf; /* buffer for IPC_INFO */
388 };
389 #endif
390 
391 /* Create the semaphore.  Return 1 if successful, 0 otherwise */
392 static int os_createmutex(int *semid) {
393 	int retVal;
394 	union semun sem_union;
395 
396 	if (semid == NULL) {
397 		return (0);
398 	}
399 
400 	retVal = semget(IPC_PRIVATE, 1, IPC_CREAT);
401 	if (retVal == -1) {
402 		return (0);
403 	}
404 
405 	*semid = retVal; /* save key of created semaphore */
406 	sem_union.val = 1; /* start semaphore off signaled */
407 	retVal = semctl(*semid, 0, SETVAL, sem_union);
408 	if (retVal == -1) {
409 		return (0);
410 	}
411 
412 	return (1);
413 }
414 
415 static void os_obtainmutex(int semid) {
416 	int retVal;
417 	struct sembuf sem_b;
418 
419 	sem_b.sem_num = 0;
420 	sem_b.sem_op = -1;
421 	sem_b.sem_flg = SEM_UNDO;
422 	retVal = semop(semid, &sem_b, 1);
423 
424 }
425 
426 static void os_releasemutex(int semid) {
427 	int retVal;
428 	struct sembuf sem_b;
429 
430 	sem_b.sem_num = 0;
431 	sem_b.sem_op = 1;
432 	sem_b.sem_flg = SEM_UNDO;
433 	retVal = semop(semid, &sem_b, 1);
434 
435 }
436 
437 /* Destroy the SNMP semaphore. */
438 static void os_destroymutex(int semid) {
439 	int retVal;
440 	union semun sem_union;
441 
442 	retVal = semctl(semid, 0, IPC_RMID, sem_union);
443 
444 }
445 #endif
446 
447 
448 void InitLibrary() {
449 
450 	FILE *imaconf;
451 	char fullline[512]; /* Full line read in from IMA.conf */
452 	char pluginname[64]; /* Read in from file IMA.conf */
453 	char pluginpath[256]; /* Read in from file IMA.conf */
454 	char imaConfFilePath[256];
455 	char systemPath[256];
456 	char *charPtr;
457 	IMA_UINT dwStrLength;
458 
459 	IMA_UINT i = 0;
460 
461 	if (number_of_plugins != -1)
462 		return;
463 
464 	number_of_plugins = 0;
465 
466 	if (os_createmutex(&libMutex) == 0) {
467 		return;
468 	}
469 	os_obtainmutex(libMutex);
470 
471 	sharedNodeAlias[0] = 0;
472 	dwStrLength = 255;
473 
474 
475 
476 	/* Open configuration file from known location */
477 #ifdef WIN32
478 	if (GetSystemDirectory(systemPath, sizeof (systemPath)))
479 		sprintf(imaConfFilePath, "%s\\drivers\\etc\\ima.conf",
480 		    systemPath);
481 	else
482 		strcpy(imaConfFilePath, "ima.conf");
483 #else
484 	strcpy(imaConfFilePath, "/etc/ima.conf");
485 #endif
486 
487 	if ((imaconf = fopen(imaConfFilePath, "r")) == NULL) {
488 		os_releasemutex(libMutex);
489 		return;
490 	}
491 	/* Read in each line and load library */
492 	while ((imaconf != NULL) &&
493 	    (fgets(fullline, sizeof (fullline), imaconf))) {
494 		if ((fullline[0] != '#') && (fullline[0] != '\n')) {
495 			/* Take out the '\n' */
496 			if ((charPtr = (char *)strchr(fullline, '\n')) != NULL)
497 				*charPtr = '\0';
498 
499 			/* look for the first tab */
500 			if ((charPtr = (char *)strchr(fullline, '\t')) == NULL)
501 				charPtr = (char *)strchr(fullline, ' ');
502 
503 			/* Set Null termination for library name if found */
504 			if (charPtr != NULL) {
505 				*charPtr++ = '\0';
506 				/*
507 				 * Skip spaces and tabs until
508 				 * the next character found
509 				 */
510 				while ((*charPtr == ' ') || (*charPtr == '\t'))
511 					charPtr++;
512 			}
513 			else
514 				continue; /* May be invalid entry */
515 
516 			/* Copy library name and path */
517 			strcpy(pluginname, fullline);
518 			strcpy(pluginpath, charPtr);
519 
520 			/*
521 			 * Continue to the next line if library name or
522 			 * path is invalid
523 			 */
524 			if ((strlen(pluginname) == 0) ||
525 			    (strlen(pluginpath) == 0))
526 				continue;
527 
528 #ifdef WIN32
529 			/* Load the DLL now */
530 			plugintable[i].hPlugin = LoadLibrary(pluginpath);
531 #else
532 			/* Load the DLL now */
533 			plugintable[i].hPlugin = dlopen(pluginpath, RTLD_LAZY);
534 #endif
535 			if (plugintable[i].hPlugin != NULL) {
536 				typedef int (*InitializeFn)();
537 				InitializeFn PassFunc;
538 				IMA_STATUS status;
539 
540 				memcpy((char *)&plugintable[i].PluginName,
541 				    (char *)&pluginname, 64);
542 				memcpy((char *)
543 				    &plugintable[i].PluginPath,
544 				    (char *)&pluginpath, 256);
545 				plugintable[i].ownerId = i + 1;
546 
547 #ifdef WIN32
548 				PassFunc = (InitializeFn)
549 				    GetProcAddress(
550 				    plugintable[i].hPlugin, "Initialize");
551 #else
552 				PassFunc = (InitializeFn)
553 				    dlsym(
554 				    plugintable[i].hPlugin, "Initialize");
555 #endif
556 				if (PassFunc != NULL) {
557 					status =
558 					    PassFunc(plugintable[i].ownerId);
559 				}
560 
561 				plugintable[i].number_of_vbcallbacks = 0;
562 				plugintable[i].number_of_pccallbacks = 0;
563 				os_createmutex(&(plugintable[i].pluginMutex));
564 				i++;
565 			}
566 		}
567 	}
568 	number_of_plugins = i;
569 	os_releasemutex(libMutex);
570 }
571 
572 
573 void ExitLibrary() {
574 	IMA_UINT j;
575 	IMA_UINT i;
576 
577 	if (number_of_plugins == -1)
578 		return;
579 
580 	os_obtainmutex(libMutex);
581 	for (i = 0; i < number_of_plugins; i++) {
582 		if (plugintable[i].hPlugin != NULL) {
583 			TerminateFn ExitPassFunc;
584 
585 			os_obtainmutex(plugintable[i].pluginMutex);
586 			for (j = 0; j < plugintable[i].number_of_vbcallbacks;
587 			    j++) {
588 #define	IMA_DFOBC_STR "IMA_DeregisterForObjectVisibilityChangesFn"
589 				IMA_DeregisterForObjectVisibilityChangesFn
590 				    PassFunc;
591 #ifdef WIN32
592 				PassFunc =
593 				    (IMA_DeregisterForObjectVisibilityChangesFn)
594 				    GetProcAddress(plugintable[i].hPlugin,
595 				    IMA_DFOBC_STR);
596 #else
597 				PassFunc =
598 				    (IMA_DeregisterForObjectVisibilityChangesFn)
599 				    dlsym(plugintable[i].hPlugin,
600 				    IMA_DFOBC_STR);
601 #endif
602 				if (PassFunc != NULL) {
603 					PassFunc(plugintable[i].vbcallback[j]);
604 				}
605 #undef IMA_DFOBC_STR
606 			}
607 			plugintable[i].number_of_vbcallbacks = 0;
608 
609 			for (j = 0; j < plugintable[i].number_of_pccallbacks;
610 			    j++) {
611 				IMA_DeregisterForObjectPropertyChangesFn
612 				    PassFunc;
613 #ifdef WIN32
614 				PassFunc =
615 				    (IMA_DeregisterForObjectPropertyChangesFn)
616 				    GetProcAddress(plugintable[i].hPlugin,
617 				    "IMA_DeregisterForObjectPropertyChangesFn");
618 #else
619 				PassFunc =
620 				    (IMA_DeregisterForObjectPropertyChangesFn)
621 				    dlsym(plugintable[i].hPlugin,
622 				    "IMA_DeregisterForObjectPropertyChangesFn");
623 #endif
624 				if (PassFunc != NULL) {
625 					PassFunc(plugintable[i].pccallback[j]);
626 				}
627 			}
628 			plugintable[i].number_of_pccallbacks = 0;
629 
630 #ifdef WIN32
631 			ExitPassFunc =
632 			    (TerminateFn) GetProcAddress
633 			    (plugintable[i].hPlugin, "Terminate");
634 #else
635 			ExitPassFunc = (TerminateFn)
636 			    dlsym(plugintable[i].hPlugin, "Terminate");
637 #endif
638 			if (ExitPassFunc != NULL) {
639 				ExitPassFunc();
640 			}
641 #ifdef WIN32
642 			/* Unload DLL from memory */
643 			FreeLibrary(plugintable[i].hPlugin);
644 #else
645 			/* Unload DLL from memory */
646 			dlclose(plugintable[i].hPlugin);
647 #endif
648 			os_releasemutex(plugintable[i].pluginMutex);
649 			os_destroymutex(plugintable[i].pluginMutex);
650 		}
651 	}
652 	number_of_plugins = -1;
653 	os_releasemutex(libMutex);
654 	os_destroymutex(libMutex);
655 }
656 
657 
658 static void VisibilityCallback(
659     IMA_BOOL becomingVisible,
660     IMA_OID objectId) {
661 	IMA_UINT i, j;
662 	os_obtainmutex(libMutex);
663 	for (i = 0; i < number_of_plugins; i++) {
664 		if ((plugintable[i].hPlugin != NULL) &&
665 		    (objectId.ownerId == plugintable[i].ownerId)) {
666 			os_obtainmutex(plugintable[i].pluginMutex);
667 			for (j = 0;
668 			    j < plugintable[i].number_of_vbcallbacks;
669 			    j++) {
670 				(plugintable[i].vbcallback[j])
671 				    (becomingVisible, objectId);
672 			}
673 			os_releasemutex(plugintable[i].pluginMutex);
674 		}
675 	}
676 	os_releasemutex(libMutex);
677 
678 }
679 
680 static void PropertyCallback(
681     IMA_OID objectId) {
682 	IMA_UINT i, j;
683 
684 	os_obtainmutex(libMutex);
685 	for (i = 0; i < number_of_plugins; i++) {
686 		if ((plugintable[i].hPlugin != NULL) &&
687 		    (objectId.ownerId == plugintable[i].ownerId)) {
688 			os_obtainmutex(plugintable[i].pluginMutex);
689 			for (j = 0;
690 			    j < plugintable[i].number_of_pccallbacks;
691 			    j++) {
692 				(plugintable[i].pccallback[j])(objectId);
693 			}
694 			os_releasemutex(plugintable[i].pluginMutex);
695 		}
696 	}
697 	os_releasemutex(libMutex);
698 }
699 
700 /*
701  * Gets the date and time, in the form of an IMA_DATETIME, from the build
702  * script when compiled.
703  */
704 static void GetBuildTime(IMA_DATETIME* pdatetime) {
705 
706 #ifdef WIN32
707 	char *dayToken[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
708 	char *monthToken[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
709 	    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
710 	char monthString[4];
711 	char dayString[4];
712 	int  i;
713 
714 	sscanf(__TIME__, "%u:%u:%u", &pdatetime->tm_hour,
715 	    &pdatetime->tm_min, &pdatetime->tm_sec);
716 	sscanf(__DATE__, "%s %u %u", monthString,
717 	    &pdatetime->tm_mday, &pdatetime->tm_year);
718 	sscanf(__TIMESTAMP__, "%s", dayString);
719 
720 	pdatetime->tm_year -= 1900;
721 	pdatetime->tm_isdst = -1;
722 
723 	pdatetime->tm_wday = 0;
724 	for (i = 0;  i < 7;  i++) {
725 		if (strcmp(dayToken[i], dayString) == 0) {
726 			pdatetime->tm_wday = i;
727 			break;
728 		}
729 	}
730 
731 	pdatetime->tm_mon = 0;
732 	for (i = 0; i < 12; i++) {
733 		if (strcmp(monthToken[i], monthString) == 0) {
734 			pdatetime->tm_mon = i;
735 			break;
736 		}
737 	}
738 
739 #else
740 #if defined(BUILD_DATE)
741 	if (strptime(BUILD_DATE, "%Y/%m/%d %T %Z", pdatetime) == NULL) {
742 		memset(pdatetime, 0, sizeof (IMA_DATETIME));
743 	}
744 #else
745 	memset(pdatetime, 0, sizeof (IMA_DATETIME));
746 #endif
747 #endif
748 
749 }
750 
751 
752 
753 /*
754  * Gets the properties of the IMA library that is being used.
755  *
756  * @param pProps A pointer to an @ref IMA_LIBRARY_PROPERTIES structure
757  *    allocated by the caller.  On successful return this structure will
758  *    contain the properties of the IMA library.
759  * @return An IMA_STATUS indicating if the operation was successful or if
760  *     an error occurred.
761  * @retval IMA_SUCCESS Returned if the library properties were successfully
762  *    returned.
763  * @retval IMA_ERROR_INVALID_PARAMETER Returned if @a pProps is NULL or
764  *    specifies a memory area to which data cannot be written.
765  */
766 IMA_API IMA_STATUS IMA_GetLibraryProperties(
767     IMA_LIBRARY_PROPERTIES *pProps) {
768 
769 	char imaPath[256];
770 #ifdef WIN32
771 	HMODULE imaHandle;
772 #endif
773 
774 	if (number_of_plugins == -1)
775 		InitLibrary();
776 
777 	if (pProps == NULL)
778 		return (IMA_ERROR_INVALID_PARAMETER);
779 
780 	// Fill in the library properties.
781 	GetBuildTime(&pProps->buildTime);
782 	pProps->supportedImaVersion = LIBRARY_PROPERTY_SUPPORTED_IMA_VERSION;
783 	libSwprintf(pProps->implementationVersion, L"%ls",
784 	    LIBRARY_PROPERTY_IMPLEMENTATION_VERSION);
785 	libSwprintf(pProps->vendor, L"%ls", LIBRARY_PROPERTY_VENDOR);
786 
787 
788 #ifdef WIN32
789 	imaHandle = GetModuleHandleA("ima");
790 	imaPath[0] = 0;
791 	if (imaHandle != NULL) {
792 		GetModuleFileNameA(imaHandle, imaPath, 256);
793 	}
794 	MultiByteToWideChar(CP_ACP, 0, imaPath, -1,
795 	pProps->fileName, 256);
796 #else
797 	libSwprintf(pProps->fileName, LIBRARY_FILE_NAME);
798 
799 	//  mbstowcs(pProps->fileName, imaPath, 256);
800 #endif
801 
802 	return (IMA_STATUS_SUCCESS);
803 }
804 
805 
806 /*
807  * Gets a list of the object IDs of all currently loaded plugins.
808  *
809  * @param ppList A pointer to a pointer to an @ref IMA_OID_LIST.
810  *    On successful return this will contain a pointer to an @ref
811  *    IMA_OID_LIST which contains the object IDs of all of the plugins
812  *    currently loaded by the library.
813  * @return An IMA_STATUS indicating if the operation was successful
814  *    or if an error occurred.
815  * @retval IMA_SUCCESS Returned if the plugin ID list was successfully
816  *    returned.
817  * @retval IMA_ERROR_INVALID_PARAMETER Returned if @a ppList is NULL or
818  *    specifies a memory area to which data cannot be written.
819  */
820 IMA_API IMA_STATUS IMA_GetPluginOidList(
821     IMA_OID_LIST **ppList) {
822 	IMA_UINT i;
823 
824 
825 	if (number_of_plugins == -1)
826 		InitLibrary();
827 
828 	if (ppList == NULL)
829 		return (IMA_ERROR_INVALID_PARAMETER);
830 
831 	os_obtainmutex(libMutex);
832 
833 	*ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST) +
834 	    (number_of_plugins - 1) * sizeof (IMA_OID));
835 
836 	if ((*ppList) == NULL)
837 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
838 
839 	(*ppList)->oidCount = number_of_plugins;
840 
841 	for (i = 0; i < number_of_plugins; i++) {
842 
843 		(*ppList)->oids[i].objectType = IMA_OBJECT_TYPE_PLUGIN;
844 		(*ppList)->oids[i].ownerId = plugintable[i].ownerId;
845 		(*ppList)->oids[i].objectSequenceNumber = 0;
846 
847 	}
848 	os_releasemutex(libMutex);
849 	return (IMA_STATUS_SUCCESS);
850 }
851 
852 
853 
854 
855 /*
856  * Gets the properties of the specified vendor plugin.
857  *
858  * @param pluginId The ID of the plugin whose properties are being retrieved.
859  * @param pProps A pointer to an @ref IMA_PLUGIN_PROPERTIES structure
860  *    allocated by the caller.  On successful return this will contain the
861  *    properties of the plugin specified by pluginId.
862  * @return An IMA_STATUS indicating if the operation was successful or if
863  *    an error occurred.
864  * @retval IMA_SUCCESS Returned if the plugin properties were successfully
865  *    returned.
866  * @retval IMA_ERROR_INVALID_OBJECT_TYPE Returned if @a pluginId does not
867  *    specify any valid object type.
868  * @retval IMA_ERROR_INCORRECT_OBJECT_TYPE Returned if @a pluginId does not
869  *    specify a plugin object.
870  * @retval IMA_ERROR_OBJECT_NOT_FOUND Returned if @a pluginId refers to a
871  *     plugin, but not one that is currently loaded.
872  * @retval IMA_ERROR_INVALID_PARAMETER Returned if @a pProps is NULL or
873  *    specify a memory area to which data cannot be written.
874  */
875 IMA_API IMA_STATUS IMA_GetPluginProperties(
876     IMA_OID pluginOid,
877     IMA_PLUGIN_PROPERTIES *pProps) {
878 	IMA_GetPluginPropertiesFn PassFunc;
879 	IMA_UINT i;
880 	IMA_STATUS status;
881 
882 	if (number_of_plugins == -1)
883 		InitLibrary();
884 
885 	if (pProps == NULL)
886 		return (IMA_ERROR_INVALID_PARAMETER);
887 
888 	if ((pluginOid.objectType != IMA_OBJECT_TYPE_PLUGIN) ||
889 	    (pluginOid.objectSequenceNumber != 0))
890 		return (IMA_ERROR_INVALID_PARAMETER);
891 
892 	os_obtainmutex(libMutex);
893 	status = IMA_ERROR_OBJECT_NOT_FOUND;
894 
895 	for (i = 0; i < number_of_plugins; i++) {
896 		if (plugintable[i].ownerId == pluginOid.ownerId) {
897 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
898 			if (plugintable[i].hPlugin != NULL) {
899 				os_obtainmutex(plugintable[i].pluginMutex);
900 #ifdef WIN32
901 				PassFunc = (IMA_GetPluginPropertiesFn)
902 				    GetProcAddress(plugintable[i].hPlugin,
903 				    "IMA_GetPluginProperties");
904 #else
905 				PassFunc = (IMA_GetPluginPropertiesFn)
906 				    dlsym(plugintable[i].hPlugin,
907 				    "IMA_GetPluginProperties");
908 #endif
909 				if (PassFunc != NULL) {
910 					status = PassFunc(pluginOid, pProps);
911 				}
912 				os_releasemutex(plugintable[i].pluginMutex);
913 			}
914 
915 			break;
916 		}
917 	}
918 	os_releasemutex(libMutex);
919 	return (status);
920 
921 }
922 
923 
924 
925 
926 /*
927  * Gets the object ID for the plugin associated with the specified object ID.
928  *
929  * @param objectId The object ID of an object that has been received from
930  *    a previous library call.
931  * @param pPluginId A pointer to an @ref IMA_OID structure allocated by the
932  *    caller.  On successful return this will contain the object ID of the
933  *    plugin associated with the object specified by @a objectId.  This
934  *    can then be used to work with the plugin, e.g., to get the
935  *    properties of the plugin or the send the plugin an IOCtl.
936  * @return An IMA_STATUS indicating if the operation was successful or if
937  *    an error occurred.
938  * @retval IMA_SUCCESS Returned if the associated plugin ID was
939  *    successfully returned.
940  * @retval IMA_ERROR_INVALID_PARAMETER Returned if @a pPluginId is NULL
941  *    or specifes a memory area to which data cannot be written.
942  * @retval IMA_ERROR_INVALID_PARAMETER Returned if @a objectId specifies
943  *    an object not owned by a plugin, but instead one that is owned by
944  *    the library.
945  * @retval IMA_ERROR_INVALID_OBJECT_TYPE Returned if @a objectId specifies
946  *    an object with an invalid type.
947  */
948 IMA_API IMA_STATUS IMA_GetAssociatedPluginOid(
949     IMA_OID objectId,
950     IMA_OID *pPluginId) {
951 	IMA_UINT i;
952 	IMA_STATUS status;
953 
954 
955 	if (number_of_plugins == -1)
956 		InitLibrary();
957 
958 	if (pPluginId == NULL || objectId.ownerId == RL_LIBRARY_SEQNUM)
959 		return (IMA_ERROR_INVALID_PARAMETER);
960 
961 	if (objectId.objectType != IMA_OBJECT_TYPE_UNKNOWN &&
962 	    objectId.objectType != IMA_OBJECT_TYPE_PLUGIN &&
963 	    objectId.objectType != IMA_OBJECT_TYPE_NODE &&
964 	    objectId.objectType != IMA_OBJECT_TYPE_LHBA &&
965 	    objectId.objectType != IMA_OBJECT_TYPE_PHBA &&
966 	    objectId.objectType != IMA_OBJECT_TYPE_NETWORK_PORTAL &&
967 	    objectId.objectType != IMA_OBJECT_TYPE_PORTAL_GROUP &&
968 	    objectId.objectType != IMA_OBJECT_TYPE_LNP &&
969 	    objectId.objectType != IMA_OBJECT_TYPE_PNP &&
970 	    objectId.objectType != IMA_OBJECT_TYPE_TARGET &&
971 	    objectId.objectType != IMA_OBJECT_TYPE_LU &&
972 	    objectId.objectType != IMA_OBJECT_TYPE_DISCOVERY_ADDRESS &&
973 	    objectId.objectType != IMA_OBJECT_TYPE_STATIC_DISCOVERY_TARGET)
974 		return (IMA_ERROR_INVALID_OBJECT_TYPE);
975 
976 	os_obtainmutex(libMutex);
977 
978 	status = IMA_ERROR_OBJECT_NOT_FOUND;
979 	for (i = 0; i < number_of_plugins; i++) {
980 		if (objectId.ownerId == plugintable[i].ownerId) {
981 			pPluginId->objectType = IMA_OBJECT_TYPE_PLUGIN;
982 			pPluginId->ownerId = plugintable[i].ownerId;
983 			pPluginId->objectSequenceNumber = 0;
984 			status = IMA_STATUS_SUCCESS;
985 		}
986 
987 	}
988 	os_releasemutex(libMutex);
989 	return (status);
990 }
991 
992 
993 
994 
995 /*
996  * Gets the object ID of the shared node.
997  *
998  * @param pSharedNodeId A pointer to an @ref IMA_OID structure allocated by
999  *    the caller.  On successful return it will contain the object ID of the
1000  *    shared node of the currently executing system is placed.
1001  * @return An IMA_STATUS indicating if the operation was successful or if
1002  *    an error occurred.
1003  * @retval IMA_SUCCESS Returned if the shared node ID has been successfully
1004  *    retrieved.
1005  * @retval IMA_ERROR_INVALID_PARAMETER Returned if @a pSharedNodeId is NULL
1006  *    or specifies a memory area to which data cannot be written.
1007  */
1008 IMA_API IMA_STATUS IMA_GetSharedNodeOid(
1009     IMA_OID *pSharedNodeId) {
1010 	if (pSharedNodeId == NULL)
1011 		return (IMA_ERROR_INVALID_PARAMETER);
1012 
1013 	pSharedNodeId->objectType = IMA_OBJECT_TYPE_NODE;
1014 	pSharedNodeId->ownerId = RL_LIBRARY_SEQNUM;
1015 	pSharedNodeId->objectSequenceNumber = RL_SHARED_NODE_SEQNUM;
1016 	return (IMA_STATUS_SUCCESS);
1017 }
1018 
1019 
1020 IMA_API IMA_STATUS IMA_GetObjectType(
1021     IMA_OID oid,
1022     IMA_OBJECT_TYPE *pObjectType) {
1023 	IMA_STATUS status;
1024 	IMA_UINT i;
1025 
1026 	if (pObjectType == NULL)
1027 		return (IMA_ERROR_INVALID_PARAMETER);
1028 
1029 	if (oid.objectType != IMA_OBJECT_TYPE_UNKNOWN &&
1030 	    oid.objectType != IMA_OBJECT_TYPE_PLUGIN &&
1031 	    oid.objectType != IMA_OBJECT_TYPE_NODE &&
1032 	    oid.objectType != IMA_OBJECT_TYPE_LHBA &&
1033 	    oid.objectType != IMA_OBJECT_TYPE_PHBA &&
1034 	    oid.objectType != IMA_OBJECT_TYPE_NETWORK_PORTAL &&
1035 	    oid.objectType != IMA_OBJECT_TYPE_PORTAL_GROUP &&
1036 	    oid.objectType != IMA_OBJECT_TYPE_LNP &&
1037 	    oid.objectType != IMA_OBJECT_TYPE_PNP &&
1038 	    oid.objectType != IMA_OBJECT_TYPE_TARGET &&
1039 	    oid.objectType != IMA_OBJECT_TYPE_LU &&
1040 	    oid.objectType != IMA_OBJECT_TYPE_DISCOVERY_ADDRESS &&
1041 	    oid.objectType != IMA_OBJECT_TYPE_STATIC_DISCOVERY_TARGET)
1042 		return (IMA_ERROR_INVALID_OBJECT_TYPE);
1043 
1044 	os_obtainmutex(libMutex);
1045 	status = IMA_ERROR_OBJECT_NOT_FOUND;
1046 
1047 	for (i = 0; i < number_of_plugins; i++) {
1048 		if (plugintable[i].ownerId == oid.ownerId) {
1049 			*pObjectType = oid.objectType;
1050 			status = IMA_STATUS_SUCCESS;
1051 		}
1052 	}
1053 	os_releasemutex(libMutex);
1054 	return (status);
1055 }
1056 
1057 
1058 
1059 /*
1060  * Gets the properties of the specified iSCSI node.
1061  * @param nodeId The ID of the node to get the properties of.
1062  * @param pProps A pointer to an @ref IMA_NODE_PROPERTIES structure
1063  *    which on successfully return
1064  *    will contain the properties of the specified node.
1065  * @return An IMA_STATUS indicating if the operation was successful or
1066  *    if an error occurred.
1067  * @retval IMA_SUCCESS Returned if the node properties have been
1068  *    successfully retrieved.
1069  * @retval IMA_ERROR_INVALID_PARAMETER Returned if @a pProps is NULL
1070  *    or specifies a memory area to which data cannot be written.
1071  * @retval IMA_ERROR_INVALID_OBJECT_TYPE Returned if @a nodeId does
1072  *     not specify any valid object type.
1073  * @retval IMA_ERROR_INCORRECT_OBJECT_TYPE Returned if @a nodeId does
1074  *    not specify a node object.
1075  * @retval IMA_ERROR_OBJECT_NOT_FOUND Returned if @a nodeId does not
1076  *    specify a node which is currently known to the system.
1077  */
1078 IMA_API IMA_STATUS IMA_GetNodeProperties(
1079     IMA_OID nodeOid,
1080     IMA_NODE_PROPERTIES *pProps) {
1081 	IMA_GetNodePropertiesFn PassFunc;
1082 	IMA_UINT i;
1083 	IMA_STATUS status;
1084 	char fullline[512]; /* Full line read in from IMA.conf */
1085 	char nodename[256];
1086 	IMA_UINT dwStrLength;
1087 
1088 	if (number_of_plugins == -1)
1089 		InitLibrary();
1090 
1091 	if (pProps == NULL)
1092 		return (IMA_ERROR_INVALID_PARAMETER);
1093 
1094 	if (nodeOid.objectType != IMA_OBJECT_TYPE_NODE)
1095 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
1096 
1097 	if ((nodeOid.ownerId == RL_LIBRARY_SEQNUM) &&
1098 	    (nodeOid.objectSequenceNumber == RL_SHARED_NODE_SEQNUM)) {
1099 		pProps->runningInInitiatorMode = IMA_TRUE;
1100 		pProps->runningInTargetMode = IMA_TRUE;
1101 		pProps->nameAndAliasSettable = IMA_TRUE;
1102 
1103 		if (sharedNodeName[0] == 0) {
1104 #if defined(_WINDOWS)
1105 			GetComputerName((char *)fullline,
1106 			    (LPDWORD)&dwStrLength);
1107 			sprintf(nodename, DEFAULT_NODE_NAME_FORMAT, fullline);
1108 			MultiByteToWideChar(CP_ACP, 0, nodename, -1,
1109 			    sharedNodeName, 256);
1110 #elif defined(SOLARIS)
1111 
1112 			if (getSolarisSharedNodeName(sharedNodeName) !=
1113 			    IMA_STATUS_SUCCESS) {
1114 				gethostname((char *)fullline, &dwStrLength);
1115 				sprintf(nodename,
1116 				    DEFAULT_NODE_NAME_FORMAT, fullline);
1117 				mbstowcs(sharedNodeName, nodename, 256);
1118 			}
1119 #else
1120 			gethostname((char *)fullline, &dwStrLength);
1121 			sprintf(nodename, DEFAULT_NODE_NAME_FORMAT, fullline);
1122 			mbstowcs(sharedNodeName, nodename, 256);
1123 #endif
1124 		}
1125 
1126 		if (sharedNodeName[0] != 0) {
1127 			libSwprintf(pProps->name, L"%ls", sharedNodeName);
1128 			pProps->nameValid = IMA_TRUE;
1129 		}
1130 		else
1131 			pProps->nameValid = IMA_FALSE;
1132 
1133 #if defined(SOLARIS)
1134 		if (sharedNodeAlias[0] == 0) {
1135 			getSolarisSharedNodeAlias(sharedNodeAlias);
1136 		}
1137 #endif
1138 
1139 		if (sharedNodeAlias[0] != 0) {
1140 			libSwprintf(pProps->alias, L"%ls", sharedNodeAlias);
1141 			pProps->aliasValid = IMA_TRUE;
1142 		}
1143 		else
1144 			pProps->aliasValid = IMA_FALSE;
1145 
1146 		return (IMA_STATUS_SUCCESS);
1147 	}
1148 
1149 	os_obtainmutex(libMutex);
1150 	status = IMA_ERROR_OBJECT_NOT_FOUND;
1151 
1152 	for (i = 0; i < number_of_plugins; i++) {
1153 		if (plugintable[i].ownerId == nodeOid.ownerId) {
1154 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
1155 			if (plugintable[i].hPlugin != NULL) {
1156 				os_obtainmutex(plugintable[i].pluginMutex);
1157 #ifdef WIN32
1158 				PassFunc = (IMA_GetNodePropertiesFn)
1159 				    GetProcAddress(plugintable[i].hPlugin,
1160 				    "IMA_GetNodeProperties");
1161 #else
1162 				PassFunc = (IMA_GetNodePropertiesFn)
1163 				    dlsym(plugintable[i].hPlugin,
1164 				    "IMA_GetNodeProperties");
1165 #endif
1166 
1167 				if (PassFunc != NULL) {
1168 					status = PassFunc(nodeOid, pProps);
1169 				}
1170 				os_releasemutex(plugintable[i].pluginMutex);
1171 			}
1172 
1173 			break;
1174 		}
1175 	}
1176 	os_releasemutex(libMutex);
1177 	return (status);
1178 
1179 }
1180 
1181 
1182 
1183 
1184 /*
1185  * Sets the name of the specified node.
1186  *
1187  * @param nodeId The object ID of the node whose name is being set.
1188  * @param newName The new name of the node.
1189  * @return An IMA_STATUS indicating if the operation was successful or if
1190  *    an error occurred.
1191  * @retval IMA_SUCCESS Returned if the node name was successfully changed.
1192  * @retval IMA_STATUS_REBOOT_NECESSARY Returned if a reboot is necessary
1193  *    before the setting of the name actually takes affect.
1194  * @retval IMA_ERROR_INVALID_PARAMETER Returned if @a newname is NULL, or
1195  *    specifies a memory area to which data cannot be written, or has a
1196  *    length of 0.
1197  * @retval IMA_ERROR_INVALID_OBJECT_TYPE Returned if @a nodeId does not
1198  *    specify any valid object type.
1199  * @retval IMA_ERROR_INCORRECT_OBJECT_TYPE Returned if @a nodeId does not
1200  *    specify a node object.
1201  * @retval IMA_ERROR_OBJECT_NOT_FOUND Returned if @a nodeId does not specify a
1202  *    node which is currently known to the system.
1203  * @retval IMA_ERROR_NAME_TOO_LONG Returned if @a newName contains too many
1204  *    characters.
1205  */
1206 IMA_API IMA_STATUS IMA_SetNodeName(
1207     IMA_OID nodeOid,
1208     const IMA_NODE_NAME newName) {
1209 	IMA_SetNodeNameFn PassFunc;
1210 	IMA_UINT i;
1211 	IMA_STATUS status;
1212 
1213 	if (number_of_plugins == -1)
1214 		InitLibrary();
1215 
1216 	if (newName == NULL || wcslen(newName) == 0)
1217 		return (IMA_ERROR_INVALID_PARAMETER);
1218 
1219 	if (wcslen(newName) > IMA_NODE_NAME_LEN - 1)
1220 		return (IMA_ERROR_NAME_TOO_LONG);
1221 
1222 	if (nodeOid.objectType != IMA_OBJECT_TYPE_NODE)
1223 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
1224 
1225 	if ((nodeOid.ownerId == RL_LIBRARY_SEQNUM) &&
1226 	    (nodeOid.objectSequenceNumber == RL_SHARED_NODE_SEQNUM)) {
1227 #if defined(SOLARIS)
1228 		if (setSolarisSharedNodeName(newName) != IMA_STATUS_SUCCESS) {
1229 			return (IMA_ERROR_UNKNOWN_ERROR);
1230 		}
1231 #endif
1232 		os_obtainmutex(libMutex);
1233 		libSwprintf(sharedNodeName, L"%ls", newName);
1234 		os_releasemutex(libMutex);
1235 		return (IMA_STATUS_SUCCESS);
1236 	}
1237 
1238 	os_obtainmutex(libMutex);
1239 	status = IMA_ERROR_OBJECT_NOT_FOUND;
1240 
1241 	for (i = 0; i < number_of_plugins; i++) {
1242 		if (plugintable[i].ownerId == nodeOid.ownerId) {
1243 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
1244 			if (plugintable[i].hPlugin != NULL) {
1245 				os_obtainmutex(plugintable[i].pluginMutex);
1246 #ifdef WIN32
1247 				PassFunc = (IMA_SetNodeNameFn)
1248 				    GetProcAddress(plugintable[i].hPlugin,
1249 				    "IMA_SetNodeName");
1250 #else
1251 				PassFunc = (IMA_SetNodeNameFn)
1252 				    dlsym(plugintable[i].hPlugin,
1253 				    "IMA_SetNodeName");
1254 #endif
1255 
1256 				if (PassFunc != NULL) {
1257 					status = PassFunc(nodeOid, newName);
1258 				}
1259 				os_releasemutex(plugintable[i].pluginMutex);
1260 			}
1261 
1262 			break;
1263 		}
1264 	}
1265 	os_releasemutex(libMutex);
1266 	return (status);
1267 
1268 }
1269 
1270 
1271 
1272 
1273 /*
1274  * Generates an unique node name for the currently running system.
1275  *
1276  * @param generatedname On successful return contains the generated node
1277  *    name.
1278  * @return An IMA_STATUS indicating if the operation was successful or if
1279  *    an error occurred.
1280  * @retval IMA_ERROR_INVALID_PARAMETER Returned if @a generatedname is NULL
1281  *    or specifies a memory area to which data cannot be written.
1282  */
1283 IMA_API IMA_STATUS IMA_GenerateNodeName(
1284     IMA_NODE_NAME generatedname) {
1285 	char computername[256];
1286 	char nodename[256];
1287 	IMA_UINT dwStrLength;
1288 #ifndef _WINDOWS
1289 #ifndef SOLARIS
1290 	int i;
1291 #endif
1292 #endif
1293 
1294 	dwStrLength = 255;
1295 
1296 	if (generatedname == NULL)
1297 		return (IMA_ERROR_INVALID_PARAMETER);
1298 
1299 #if defined(_WINDOWS)
1300 	GetComputerName((char *)computername, (LPDWORD)&dwStrLength);
1301 	_strlwr(computername);
1302 	_snprintf(nodename, 256, DEFAULT_NODE_NAME_FORMAT, computername);
1303 	MultiByteToWideChar(CP_ACP, 0, nodename, -1,
1304 	generatedname, 256);
1305 #elif defined(SOLARIS)
1306 	if (getSolarisSharedNodeName(generatedname) != IMA_STATUS_SUCCESS) {
1307 		gethostname(computername, &dwStrLength);
1308 		sprintf(nodename, DEFAULT_NODE_NAME_FORMAT, generatedname);
1309 		mbstowcs(generatedname, nodename, 256);
1310 	}
1311 #else
1312 	gethostname((char *)computername, &dwStrLength);
1313 	i = 0;
1314 	while (computername[i] != '\0') {
1315 		computername[i] = tolower(computername[i]);
1316 		i++;
1317 	}
1318 	snprintf(nodename, 256, DEFAULT_NODE_NAME_FORMAT, computername);
1319 	mbstowcs(generatedname, nodename, 256);
1320 #endif
1321 
1322 	return (IMA_STATUS_SUCCESS);
1323 }
1324 
1325 
1326 /*
1327  * Sets the alias of the specified node.
1328  *
1329  * @param nodeId The object ID of the node whose alias is being set.
1330  * @param newAlias A pointer to a Unicode string which contains the new node
1331  *    alias.If this parameter is NULL then the current alias is deleted, in
1332  *    which case the specified node no longer has an alias.
1333  * @return An IMA_STATUS indicating if the operation was successful or if
1334  *    an error occurred.
1335  * @retval IMA_SUCCESS Returned if the node's alias has been successfully set.
1336  * @retval IMA_STATUS_REBOOT_NECESSARY A reboot is necessary before
1337  *    the setting of the
1338  *    alias actually takes affect.
1339  * @retval IMA_ERROR_INVALID_OBJECT_TYPE Returned if @a nodeId does not
1340  *    specify any valid object type.
1341  * @retval IMA_ERROR_INCORRECT_OBJECT_TYPE Returned if @a nodeId does not
1342  *    specify a node object.
1343  * @retval IMA_ERROR_OBJECT_NOT_FOUND Returned if @a nodeId does not specify
1344  *    a node which is currently known to the system.
1345  * @retval IMA_ERROR_NAME_TOO_LONG Returned if @a newAlias contains too many
1346  *               characters.
1347  */
1348 IMA_API IMA_STATUS IMA_SetNodeAlias(
1349     IMA_OID nodeOid,
1350     const IMA_NODE_ALIAS newAlias) {
1351 	IMA_SetNodeAliasFn PassFunc;
1352 	IMA_UINT i;
1353 	IMA_STATUS status;
1354 
1355 	if (number_of_plugins == -1)
1356 		InitLibrary();
1357 
1358 	if (newAlias == NULL)
1359 		return (IMA_ERROR_INVALID_PARAMETER);
1360 
1361 	if (wcslen(newAlias) > IMA_NODE_ALIAS_LEN - 1)
1362 		return (IMA_ERROR_NAME_TOO_LONG);
1363 
1364 	if (nodeOid.objectType != IMA_OBJECT_TYPE_NODE)
1365 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
1366 
1367 	if ((nodeOid.ownerId == RL_LIBRARY_SEQNUM) &&
1368 	    (nodeOid.objectSequenceNumber == RL_SHARED_NODE_SEQNUM)) {
1369 #if defined(SOLARIS)
1370 		if (setSolarisSharedNodeAlias(newAlias) != IMA_STATUS_SUCCESS) {
1371 			return (IMA_ERROR_UNKNOWN_ERROR);
1372 		}
1373 #endif
1374 		os_obtainmutex(libMutex);
1375 		if (wcslen(newAlias) > 0 && newAlias != NULL)
1376 			libSwprintf(sharedNodeAlias, L"%ls", newAlias);
1377 		else
1378 			libSwprintf(sharedNodeAlias, L"%ls", "");
1379 
1380 		os_releasemutex(libMutex);
1381 		return (IMA_STATUS_SUCCESS);
1382 	}
1383 
1384 	os_obtainmutex(libMutex);
1385 	status = IMA_ERROR_OBJECT_NOT_FOUND;
1386 
1387 	for (i = 0; i < number_of_plugins; i++) {
1388 		if (plugintable[i].ownerId == nodeOid.ownerId) {
1389 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
1390 			if (plugintable[i].hPlugin != NULL) {
1391 				os_obtainmutex(plugintable[i].pluginMutex);
1392 #ifdef WIN32
1393 				PassFunc = (IMA_SetNodeAliasFn)
1394 				    GetProcAddress(plugintable[i].hPlugin,
1395 				    "IMA_SetNodeAlias");
1396 #else
1397 				PassFunc = (IMA_SetNodeAliasFn)
1398 				    dlsym(
1399 				    plugintable[i].hPlugin,
1400 				    "IMA_SetNodeAlias");
1401 #endif
1402 
1403 				if (PassFunc != NULL) {
1404 					status = PassFunc(nodeOid, newAlias);
1405 				}
1406 				os_releasemutex(plugintable[i].pluginMutex);
1407 			}
1408 
1409 			break;
1410 		}
1411 	}
1412 	os_releasemutex(libMutex);
1413 	return (status);
1414 }
1415 
1416 
1417 
1418 
1419 /*
1420  * Gets a list of the object IDs of all the logical HBAs in the system.
1421  *
1422  * @param ppList A pointer to a pointer to an @ref IMA_OID_LIST structure.
1423  *    on successful return this will contain a pointer to an
1424  *    @ref IMA_OID_LIST which contains the object IDs of all of the
1425  *    LHBAs currently in the system.
1426  * @return An IMA_STATUS indicating if the operation was successful or if
1427  *    an error occurred.
1428  * @retval IMA_SUCCESS Returned if the LHBA ID list has been successfully
1429  *    returned.
1430  * @retval IMA_ERROR_INVALID_PARAMETER Returned if @a ppList is NULL or
1431  *   specifies a
1432  *   memory area to which data cannot be written.
1433  */
1434 IMA_API IMA_STATUS IMA_GetLhbaOidList(
1435     IMA_OID_LIST **ppList) {
1436 	IMA_GetLhbaOidListFn PassFunc;
1437 	IMA_FreeMemoryFn FreeFunc;
1438 
1439 	IMA_UINT i;
1440 	IMA_UINT j;
1441 	IMA_UINT totalIdCount;
1442 	IMA_STATUS status;
1443 
1444 	if (number_of_plugins == -1)
1445 		InitLibrary();
1446 
1447 	if (ppList == NULL)
1448 		return (IMA_ERROR_INVALID_PARAMETER);
1449 
1450 	os_obtainmutex(libMutex);
1451 	// Get total id count first
1452 	totalIdCount = 0;
1453 
1454 	for (i = 0; i < number_of_plugins; i++) {
1455 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
1456 		if (plugintable[i].hPlugin != NULL) {
1457 			os_obtainmutex(plugintable[i].pluginMutex);
1458 #ifdef WIN32
1459 			PassFunc = (IMA_GetLhbaOidListFn)
1460 			    GetProcAddress(plugintable[i].hPlugin,
1461 			    "IMA_GetLhbaOidList");
1462 #else
1463 			PassFunc = (IMA_GetLhbaOidListFn)
1464 			    dlsym(plugintable[i].hPlugin,
1465 			    "IMA_GetLhbaOidList");
1466 #endif
1467 			if (PassFunc != NULL) {
1468 				IMA_OID_LIST *ppOidList;
1469 				status = PassFunc(&ppOidList);
1470 				if (status == IMA_STATUS_SUCCESS) {
1471 					totalIdCount += ppOidList->oidCount;
1472 #ifdef WIN32
1473 					FreeFunc = (IMA_FreeMemoryFn)
1474 					    GetProcAddress(
1475 					    plugintable[i].hPlugin,
1476 					    "IMA_FreeMemory");
1477 #else
1478 					FreeFunc = (IMA_FreeMemoryFn)
1479 					    dlsym(plugintable[i].hPlugin,
1480 					    "IMA_FreeMemory");
1481 #endif
1482 					if (FreeFunc != NULL) {
1483 						FreeFunc(ppOidList);
1484 					}
1485 				}
1486 
1487 			}
1488 			os_releasemutex(plugintable[i].pluginMutex);
1489 		}
1490 		if (status != IMA_STATUS_SUCCESS) {
1491 			break;
1492 		}
1493 	}
1494 
1495 
1496 	*ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST) +
1497 	    (totalIdCount - 1) * sizeof (IMA_OID));
1498 
1499 	if ((*ppList) == NULL) {
1500 		os_releasemutex(libMutex);
1501 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1502 	}
1503 	(*ppList)->oidCount = totalIdCount;
1504 
1505 	// 2nd pass to copy the id lists
1506 	totalIdCount = 0;
1507 	status = IMA_STATUS_SUCCESS;
1508 	for (i = 0; i < number_of_plugins; i++) {
1509 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
1510 		if (plugintable[i].hPlugin != NULL) {
1511 			os_obtainmutex(plugintable[i].pluginMutex);
1512 #ifdef WIN32
1513 			PassFunc = (IMA_GetLhbaOidListFn)
1514 			    GetProcAddress(plugintable[i].hPlugin,
1515 			    "IMA_GetLhbaOidList");
1516 #else
1517 			PassFunc = (IMA_GetLhbaOidListFn)
1518 			    dlsym(plugintable[i].hPlugin,
1519 			    "IMA_GetLhbaOidList");
1520 #endif
1521 			if (PassFunc != NULL) {
1522 				IMA_OID_LIST *ppOidList;
1523 				status = PassFunc(&ppOidList);
1524 				if (status == IMA_STATUS_SUCCESS) {
1525 					for (j = 0;
1526 					    (j < ppOidList->oidCount) &&
1527 					    (totalIdCount <
1528 					    (*ppList)->oidCount);
1529 					    j++) {
1530 						(*ppList)->oids[totalIdCount].
1531 						    objectType
1532 						    = ppOidList->oids[j].
1533 						    objectType;
1534 						(*ppList)->oids[totalIdCount].
1535 						    objectSequenceNumber =
1536 						    ppOidList->oids[j].
1537 						    objectSequenceNumber;
1538 						(*ppList)->oids[totalIdCount].
1539 						    ownerId =
1540 						    ppOidList->oids[j].ownerId;
1541 						totalIdCount++;
1542 					}
1543 #ifdef WIN32
1544 					FreeFunc = (IMA_FreeMemoryFn)
1545 					    GetProcAddress(
1546 					    plugintable[i].hPlugin,
1547 					    "IMA_FreeMemory");
1548 #else
1549 					FreeFunc = (IMA_FreeMemoryFn)
1550 					    dlsym(plugintable[i].hPlugin,
1551 					    "IMA_FreeMemory");
1552 #endif
1553 					if (FreeFunc != NULL) {
1554 						FreeFunc(ppOidList);
1555 					}
1556 				}
1557 			}
1558 			os_releasemutex(plugintable[i].pluginMutex);
1559 		}
1560 		if (status != IMA_STATUS_SUCCESS) {
1561 			free(*ppList);
1562 			break;
1563 		}
1564 
1565 	}
1566 	os_releasemutex(libMutex);
1567 	return (status);
1568 }
1569 
1570 
1571 
1572 
1573 /*
1574  * Gets the properties of the specified logical HBA.
1575  *
1576  * @param lhbaId The object ID of the LHBA whose properties are being
1577  *    retrieved.
1578  * @param pProps A pointer to an @ref IMA_LHBA_PROPERTIES structure.
1579  *    On successful
1580  *    return this will contain the properties of the LHBA specified by
1581  *    @a lhbaId.
1582  * @return An IMA_STATUS indicating if the operation was successful or if
1583  *    an error occurred.
1584  * @retval IMA_SUCCESS Returned if the properties of the specified LHBA
1585  *    have been successfully retrieved.
1586  * @retval IMA_ERROR_INVALID_PARAMETER Returned if @a pProps is NULL or
1587  *    specify a memory area to which data cannot be written.
1588  * @retval IMA_ERROR_INVALID_OBJECT_TYPE Returned if @a lhbaId does not
1589  *    specify any valid object type.
1590  * @retval IMA_ERROR_INCORRECT_OBJECT_TYPE Returned if @a lhbaId does not
1591  *    specify a LHBA.
1592  * @retval IMA_ERROR_OBJECT_NOT_FOUND Returned if @a lhbaId does not
1593  *    specify a LHBA which is currently known to the system.
1594  */
1595 IMA_API IMA_STATUS IMA_GetLhbaProperties(
1596     IMA_OID lhbaId,
1597     IMA_LHBA_PROPERTIES *pProps) {
1598 	IMA_GetLhbaPropertiesFn PassFunc;
1599 	IMA_UINT i;
1600 	IMA_STATUS status;
1601 
1602 	if (number_of_plugins == -1)
1603 		InitLibrary();
1604 
1605 	if (pProps == NULL)
1606 		return (IMA_ERROR_INVALID_PARAMETER);
1607 
1608 	if (lhbaId.objectType != IMA_OBJECT_TYPE_LHBA)
1609 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
1610 
1611 	os_obtainmutex(libMutex);
1612 	status = IMA_ERROR_OBJECT_NOT_FOUND;
1613 
1614 	for (i = 0; i < number_of_plugins; i++) {
1615 		if (plugintable[i].ownerId == lhbaId.ownerId) {
1616 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
1617 			if (plugintable[i].hPlugin != NULL) {
1618 				os_obtainmutex(plugintable[i].pluginMutex);
1619 #ifdef WIN32
1620 				PassFunc = (IMA_GetLhbaPropertiesFn)
1621 				    GetProcAddress(plugintable[i].hPlugin,
1622 				    "IMA_GetLhbaProperties");
1623 #else
1624 				PassFunc = (IMA_GetLhbaPropertiesFn)
1625 				    dlsym(plugintable[i].hPlugin,
1626 				    "IMA_GetLhbaProperties");
1627 #endif
1628 
1629 				if (PassFunc != NULL) {
1630 					status = PassFunc(lhbaId, pProps);
1631 				}
1632 				os_releasemutex(plugintable[i].pluginMutex);
1633 			}
1634 
1635 			break;
1636 		}
1637 	}
1638 	os_releasemutex(libMutex);
1639 	return (status);
1640 }
1641 
1642 
1643 
1644 
1645 /*
1646  * Gets a list of the object IDs of all the physical HBAs in the system.
1647  *
1648  * @param ppList A pointer to a pointer to an @ref IMA_OID_LIST structure.
1649  *    on successful return this will contain a pointer to an
1650  *    @ref IMA_OID_LIST which contains the object IDs of all of the
1651  *    PHBAs currently in the system.
1652  * @return An IMA_STATUS indicating if the operation was successful or if
1653  *    an error occurred.
1654  * @retval IMA_SUCCESS Returned if the PHBA ID list has been successfully
1655  *    returned.
1656  * @retval IMA_ERROR_INVALID_PARAMETER Returned if @a ppList is NULL or
1657  *    specify a memory area to which data cannot be written.
1658  * @retval IMA_SUCCESS Returned if the properties of the specified PHBA
1659  *    have been successfully retrieved.
1660  * @retval IMA_ERROR_OBJECT_NOT_FOUND Returned if @a phbaId does not
1661  *    specify a PHBA which is currently known to the system.
1662  * @retval IMA_ERROR_INVALID_PARAMETER Returned if @a ppList is NULL or
1663  *    specify a memory area to which data cannot be written.
1664  */
1665 IMA_API IMA_STATUS IMA_GetPhbaOidList(
1666     IMA_OID_LIST **ppList) {
1667 	IMA_GetPhbaOidListFn PassFunc;
1668 	IMA_FreeMemoryFn FreeFunc;
1669 
1670 	IMA_UINT i;
1671 	IMA_UINT j;
1672 	IMA_UINT totalIdCount;
1673 	IMA_STATUS status;
1674 
1675 	if (number_of_plugins == -1)
1676 		InitLibrary();
1677 
1678 	if (ppList == NULL)
1679 		return (IMA_ERROR_INVALID_PARAMETER);
1680 
1681 	os_obtainmutex(libMutex);
1682 	// Get total id count first
1683 	totalIdCount = 0;
1684 
1685 	for (i = 0; i < number_of_plugins; i++) {
1686 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
1687 		if (plugintable[i].hPlugin != NULL) {
1688 			os_obtainmutex(plugintable[i].pluginMutex);
1689 #ifdef WIN32
1690 			PassFunc = (IMA_GetPhbaOidListFn)
1691 			    GetProcAddress(plugintable[i].hPlugin,
1692 			    "IMA_GetPhbaOidList");
1693 #else
1694 			PassFunc = (IMA_GetPhbaOidListFn)
1695 			    dlsym(plugintable[i].hPlugin,
1696 			    "IMA_GetPhbaOidList");
1697 #endif
1698 			if (PassFunc != NULL) {
1699 				IMA_OID_LIST *ppOidList;
1700 				status = PassFunc(&ppOidList);
1701 				if (status == IMA_STATUS_SUCCESS) {
1702 					totalIdCount += ppOidList->oidCount;
1703 #ifdef WIN32
1704 					FreeFunc = (IMA_FreeMemoryFn)
1705 					    GetProcAddress(
1706 					    plugintable[i].hPlugin,
1707 					    "IMA_FreeMemory");
1708 #else
1709 					FreeFunc = (IMA_FreeMemoryFn)
1710 					    dlsym(plugintable[i].hPlugin,
1711 					    "IMA_FreeMemory");
1712 #endif
1713 					if (FreeFunc != NULL) {
1714 						FreeFunc(ppOidList);
1715 					}
1716 				}
1717 			}
1718 			os_releasemutex(plugintable[i].pluginMutex);
1719 		}
1720 		if (status != IMA_STATUS_SUCCESS) {
1721 			break;
1722 		}
1723 
1724 	}
1725 
1726 
1727 	*ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST) +
1728 	    (totalIdCount - 1) * sizeof (IMA_OID));
1729 
1730 	if ((*ppList) == NULL) {
1731 		os_releasemutex(libMutex);
1732 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1733 	}
1734 
1735 	(*ppList)->oidCount = totalIdCount;
1736 
1737 	// 2nd pass to copy the id lists
1738 	totalIdCount = 0;
1739 	status = IMA_STATUS_SUCCESS;
1740 	for (i = 0; i < number_of_plugins; i++) {
1741 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
1742 		if (plugintable[i].hPlugin != NULL) {
1743 			os_obtainmutex(plugintable[i].pluginMutex);
1744 #ifdef WIN32
1745 			PassFunc = (IMA_GetPhbaOidListFn)
1746 			    GetProcAddress(plugintable[i].hPlugin,
1747 			    "IMA_GetPhbaOidList");
1748 #else
1749 			PassFunc = (IMA_GetPhbaOidListFn)
1750 			    dlsym(plugintable[i].hPlugin,
1751 			    "IMA_GetPhbaOidList");
1752 #endif
1753 			if (PassFunc != NULL) {
1754 				IMA_OID_LIST *ppOidList;
1755 				status = PassFunc(&ppOidList);
1756 				if (status == IMA_STATUS_SUCCESS) {
1757 					for (j = 0;
1758 					    (j < ppOidList->oidCount) &&
1759 					    (totalIdCount <
1760 					    (*ppList)->oidCount);
1761 					    j++) {
1762 						(*ppList)->oids[totalIdCount].
1763 						    objectType =
1764 						    ppOidList->oids[j].
1765 						    objectType;
1766 						(*ppList)->oids[totalIdCount].
1767 						    objectSequenceNumber =
1768 						    ppOidList->oids[j].
1769 						    objectSequenceNumber;
1770 						(*ppList)->oids[totalIdCount].
1771 						    ownerId =
1772 						    ppOidList->oids[j].ownerId;
1773 						totalIdCount++;
1774 					}
1775 #ifdef WIN32
1776 					FreeFunc = (IMA_FreeMemoryFn)
1777 					    GetProcAddress
1778 					    (plugintable[i].hPlugin,
1779 					    "IMA_FreeMemory");
1780 #else
1781 					FreeFunc = (IMA_FreeMemoryFn)
1782 					    dlsym(plugintable[i].hPlugin,
1783 					    "IMA_FreeMemory");
1784 #endif
1785 					if (FreeFunc != NULL) {
1786 						FreeFunc(ppOidList);
1787 					}
1788 				}
1789 			}
1790 			os_releasemutex(plugintable[i].pluginMutex);
1791 		}
1792 		if (status != IMA_STATUS_SUCCESS) {
1793 			free(*ppList);
1794 			break;
1795 		}
1796 	}
1797 	os_releasemutex(libMutex);
1798 	return (status);
1799 }
1800 
1801 
1802 /*
1803  * Gets the general properties of a physical HBA.
1804  *
1805  * @param phbaId The object ID of the PHBA whose
1806  *    properties are being queried.
1807  * @param pProps A pointer to an @ref
1808  *    IMA_PHBA_PROPERTIES structure.  On successful
1809  *    return this will contain the properties of
1810  *    the PHBA specified by @a phbaId.
1811  * @return An IMA_STATUS indicating if the
1812  *    operation was successful or if an error
1813  *    occurred.
1814  * @retval IMA_SUCCESS Returned if the properties
1815  *    of the specified PHBA have been
1816  *    successfully retrieved.
1817  * @retval IMA_ERROR_INVALID_PARAMETER Returned
1818  *    if @a pProps is NULL or specifies a
1819  *    memory area to which data cannot be written.
1820  * @retval IMA_ERROR_INVALID_OBJECT_TYPE Returned
1821  *    if @a phbaId does not specify any
1822  *    valid object type.
1823  * @retval IMA_ERROR_INCORRECT_OBJECT_TYPE Returned
1824  *    if @a phbaId does not specify a
1825  *    PHBA.
1826  * @retval IMA_ERROR_OBJECT_NOT_FOUND Returned
1827  *    if @a phbaId does not specify a PHBA
1828  *    which is currently known to the system.
1829  */
1830 IMA_API IMA_STATUS IMA_GetPhbaProperties(
1831     IMA_OID phbaId,
1832     IMA_PHBA_PROPERTIES *pProps) {
1833 	IMA_GetPhbaPropertiesFn PassFunc;
1834 	IMA_UINT i;
1835 	IMA_STATUS status;
1836 
1837 	if (number_of_plugins == -1)
1838 		InitLibrary();
1839 
1840 	if (pProps == NULL)
1841 		return (IMA_ERROR_INVALID_PARAMETER);
1842 
1843 	if (phbaId.objectType != IMA_OBJECT_TYPE_PHBA)
1844 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
1845 
1846 	os_obtainmutex(libMutex);
1847 	status = IMA_ERROR_OBJECT_NOT_FOUND;
1848 
1849 	for (i = 0; i < number_of_plugins; i++) {
1850 		if (plugintable[i].ownerId == phbaId.ownerId) {
1851 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
1852 			if (plugintable[i].hPlugin != NULL) {
1853 				os_obtainmutex(plugintable[i].pluginMutex);
1854 #ifdef WIN32
1855 				PassFunc = (IMA_GetPhbaPropertiesFn)
1856 				    GetProcAddress(plugintable[i].hPlugin,
1857 				    "IMA_GetPhbaProperties");
1858 #else
1859 				PassFunc = (IMA_GetPhbaPropertiesFn)
1860 				    dlsym(plugintable[i].hPlugin,
1861 				    "IMA_GetPhbaProperties");
1862 #endif
1863 
1864 				if (PassFunc != NULL) {
1865 					status = PassFunc(phbaId, pProps);
1866 				}
1867 				os_releasemutex(plugintable[i].pluginMutex);
1868 			}
1869 
1870 			break;
1871 		}
1872 	}
1873 	os_releasemutex(libMutex);
1874 	return (status);
1875 }
1876 
1877 /*
1878  * Frees a previously allocated IMA_OID_LIST structure.
1879  *
1880  * @param pList A pointer to an @ref IMA_OID_LIST
1881  *    structure allocated by the
1882  *    library.  On successful return the memory
1883  *    allocated by the list is freed.
1884  * @return An IMA_STATUS indicating if the operation
1885  *    was successful or if an error occurred.
1886  * @retval IMA_SUCCESS Returned if the specified object
1887  *    ID list was successfully freed.
1888  * @retval IMA_ERROR_INVALID_PARAMETER Returned
1889  *    if @a pList is NULL or specifies a
1890  *    memory area from which data cannot be read.
1891  */
1892 IMA_API IMA_STATUS IMA_FreeMemory(
1893     void *pMemory) {
1894 	if (pMemory == NULL)
1895 		return (IMA_ERROR_INVALID_PARAMETER);
1896 	free(pMemory);
1897 	return (IMA_STATUS_SUCCESS);
1898 }
1899 
1900 
1901 
1902 
1903 IMA_API IMA_STATUS IMA_GetNonSharedNodeOidList(
1904     IMA_OID_LIST **ppList) {
1905 	IMA_GetNonSharedNodeOidListFn PassFunc;
1906 	IMA_FreeMemoryFn FreeFunc;
1907 
1908 	IMA_UINT i;
1909 	IMA_UINT j;
1910 	IMA_UINT totalIdCount;
1911 	IMA_STATUS status;
1912 
1913 	if (number_of_plugins == -1)
1914 		InitLibrary();
1915 
1916 	if (ppList == NULL)
1917 		return (IMA_ERROR_INVALID_PARAMETER);
1918 
1919 	os_obtainmutex(libMutex);
1920 	// Get total id count first
1921 	totalIdCount = 0;
1922 
1923 	for (i = 0; i < number_of_plugins; i++) {
1924 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
1925 		if (plugintable[i].hPlugin != NULL) {
1926 			os_obtainmutex(plugintable[i].pluginMutex);
1927 #ifdef WIN32
1928 			PassFunc = (IMA_GetNonSharedNodeOidListFn)
1929 			    GetProcAddress(plugintable[i].hPlugin,
1930 			    "IMA_GetNonSharedNodeOidList");
1931 #else
1932 			PassFunc = (IMA_GetNonSharedNodeOidListFn)
1933 			    dlsym(plugintable[i].hPlugin,
1934 			    "IMA_GetNonSharedNodeOidList");
1935 #endif
1936 			if (PassFunc != NULL) {
1937 				IMA_OID_LIST *ppOidList;
1938 				status = PassFunc(&ppOidList);
1939 				if (status == IMA_STATUS_SUCCESS) {
1940 					totalIdCount += ppOidList->oidCount;
1941 #ifdef WIN32
1942 					FreeFunc = (IMA_FreeMemoryFn)
1943 					    GetProcAddress(
1944 					    plugintable[i].hPlugin,
1945 					    "IMA_FreeMemory");
1946 #else
1947 					FreeFunc = (IMA_FreeMemoryFn)
1948 					    dlsym(plugintable[i].hPlugin,
1949 					    "IMA_FreeMemory");
1950 #endif
1951 					if (FreeFunc != NULL) {
1952 						FreeFunc(ppOidList);
1953 					}
1954 				}
1955 			}
1956 			os_releasemutex(plugintable[i].pluginMutex);
1957 		}
1958 		if (status != IMA_STATUS_SUCCESS) {
1959 			break;
1960 		}
1961 
1962 	}
1963 
1964 	*ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST) +
1965 	    (totalIdCount - 1) * sizeof (IMA_OID));
1966 
1967 	if ((*ppList) == NULL) {
1968 		os_releasemutex(libMutex);
1969 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1970 	}
1971 
1972 	(*ppList)->oidCount = totalIdCount;
1973 
1974 	// 2nd pass to copy the id lists
1975 	totalIdCount = 0;
1976 	status = IMA_STATUS_SUCCESS;
1977 	for (i = 0; i < number_of_plugins; i++) {
1978 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
1979 		if (plugintable[i].hPlugin != NULL) {
1980 			os_obtainmutex(plugintable[i].pluginMutex);
1981 #ifdef WIN32
1982 			PassFunc = (IMA_GetNonSharedNodeOidListFn)
1983 			    GetProcAddress(plugintable[i].hPlugin,
1984 			    "IMA_GetNonSharedNodeOidList");
1985 #else
1986 			PassFunc = (IMA_GetNonSharedNodeOidListFn)
1987 			    dlsym(plugintable[i].hPlugin,
1988 			    "IMA_GetNonSharedNodeOidList");
1989 #endif
1990 			if (PassFunc != NULL) {
1991 				IMA_OID_LIST *ppOidList;
1992 				status = PassFunc(&ppOidList);
1993 				if (status == IMA_STATUS_SUCCESS) {
1994 					for (j = 0;
1995 					    (j < ppOidList->oidCount) &&
1996 					    (totalIdCount < (
1997 					    *ppList)->oidCount);
1998 					    j++) {
1999 						(*ppList)->oids[
2000 						    totalIdCount].objectType =
2001 						    ppOidList->oids[j].
2002 						    objectType;
2003 						(*ppList)->oids[totalIdCount].
2004 						    objectSequenceNumber =
2005 						    ppOidList->oids[j].
2006 						    objectSequenceNumber;
2007 						(*ppList)->oids[
2008 						    totalIdCount].
2009 						    ownerId =
2010 						    ppOidList->oids[j].
2011 						    ownerId;
2012 						totalIdCount++;
2013 					}
2014 #ifdef WIN32
2015 					FreeFunc = (IMA_FreeMemoryFn)
2016 					    GetProcAddress(
2017 					    plugintable[i].hPlugin,
2018 					    "IMA_FreeMemory");
2019 #else
2020 					FreeFunc = (IMA_FreeMemoryFn)
2021 					    dlsym(plugintable[i].hPlugin,
2022 					    "IMA_FreeMemory");
2023 #endif
2024 					if (FreeFunc != NULL) {
2025 						FreeFunc(ppOidList);
2026 					}
2027 				}
2028 			}
2029 			os_releasemutex(plugintable[i].pluginMutex);
2030 		}
2031 		if (status != IMA_STATUS_SUCCESS) {
2032 			free(*ppList);
2033 			break;
2034 		}
2035 	}
2036 	os_releasemutex(libMutex);
2037 	return (status);
2038 }
2039 
2040 
2041 
2042 /*
2043  * Gets the first burst length properties of
2044  * the specified logical HBA.
2045  *
2046  * @param lhbaId The object ID of the logical HBA
2047  *    to get the first burst length
2048  *    properties of.
2049  * @param pProps A pointer to a min/max values
2050  *    structure.
2051  * @return An IMA_STATUS indicating if the operation
2052  *    was successful or if an error
2053  *    occurred.
2054  * @retval IMA_SUCCESS Returned if the first burst
2055  *    length properties have been
2056  *    successfully retrieved.
2057  * @retval IMA_ERROR_INVALID_PARAMETER Returned
2058  *    if @a pProps is NULL or specifies a
2059  *    memory area to which data cannot be written.
2060  * @retval IMA_ERROR_INVALID_OBJECT_TYPE Returned
2061  *    if @a lhbaId does not specify any
2062  *    valid object type.
2063  * @retval IMA_ERROR_INCORRECT_OBJECT_TYPE Returned
2064  *    if @a lhbaId does not specify a LHBA.
2065  * @retval IMA_ERROR_OBJECT_NOT_FOUND Returned
2066  *    @a lhbaId does not specify a LHBA
2067  *    which is currently known to the system.
2068  */
2069 IMA_API IMA_STATUS IMA_GetFirstBurstLengthProperties(
2070     IMA_OID Oid,
2071     IMA_MIN_MAX_VALUE *pProps) {
2072 	IMA_GetFirstBurstLengthPropertiesFn PassFunc;
2073 	IMA_UINT i;
2074 	IMA_STATUS status;
2075 
2076 	if (number_of_plugins == -1)
2077 		InitLibrary();
2078 
2079 	if (pProps == NULL)
2080 		return (IMA_ERROR_INVALID_PARAMETER);
2081 
2082 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
2083 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
2084 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2085 
2086 	os_obtainmutex(libMutex);
2087 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2088 
2089 	for (i = 0; i < number_of_plugins; i++) {
2090 		if (plugintable[i].ownerId == Oid.ownerId) {
2091 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2092 			if (plugintable[i].hPlugin != NULL) {
2093 				os_obtainmutex(plugintable[i].pluginMutex);
2094 #ifdef WIN32
2095 				PassFunc =
2096 				    (IMA_GetFirstBurstLengthPropertiesFn)
2097 				    GetProcAddress(plugintable[i].hPlugin,
2098 				    "IMA_GetFirstBurstLengthProperties");
2099 #else
2100 				PassFunc =
2101 				    (IMA_GetFirstBurstLengthPropertiesFn)
2102 				    dlsym(plugintable[i].hPlugin,
2103 				    "IMA_GetFirstBurstLengthProperties");
2104 #endif
2105 
2106 				if (PassFunc != NULL) {
2107 					status = PassFunc(Oid, pProps);
2108 				}
2109 				os_releasemutex(plugintable[i].pluginMutex);
2110 			}
2111 
2112 			break;
2113 		}
2114 	}
2115 	os_releasemutex(libMutex);
2116 	return (status);
2117 }
2118 
2119 /*
2120  * Gets the max burst length properties of the
2121  * specified logical HBA.
2122  *
2123  * @param lhbaId The object ID of the logical HBA to
2124  * get the max burst length properties of.
2125  * @param pProps A pointer to an @ref IMA_MIN_MAX_VALUE
2126  *    structure allocated by the
2127  *    caller.  On successful return this structure
2128  *    will contain the max
2129  *    burst length properties of this LHBA.
2130  * @return An IMA_STATUS indicating if the operation
2131  *    was successful or if an error occurred.
2132  * @retval IMA_SUCCESS Returned if the max burst
2133  *    length properties have been
2134  *    successfully retrieved.
2135  * @retval IMA_ERROR_INVALID_PARAMETER Returned
2136  *    if @a pProps is NULL or specifies a
2137  *    memory area to which data cannot be written.
2138  * @retval IMA_ERROR_INVALID_OBJECT_TYPE Returned
2139  *    if @a lhbaId does not specify any
2140  *    valid object type.
2141  * @retval IMA_ERROR_INCORRECT_OBJECT_TYPE Returned
2142  *    if @a lhbaId does not specify a HBA.
2143  * @retval IMA_ERROR_OBJECT_NOT_FOUND Returned
2144  *    if @a lhbaId does not specify a LHBA
2145  *    which is currently known to the system.
2146  */
2147 IMA_API IMA_STATUS IMA_GetMaxBurstLengthProperties(
2148     IMA_OID Oid,
2149     IMA_MIN_MAX_VALUE *pProps) {
2150 	IMA_GetMaxBurstLengthPropertiesFn PassFunc;
2151 	IMA_UINT i;
2152 	IMA_STATUS status;
2153 
2154 	if (number_of_plugins == -1)
2155 		InitLibrary();
2156 
2157 	if (pProps == NULL)
2158 		return (IMA_ERROR_INVALID_PARAMETER);
2159 
2160 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
2161 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
2162 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2163 
2164 	os_obtainmutex(libMutex);
2165 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2166 
2167 	for (i = 0; i < number_of_plugins; i++) {
2168 		if (plugintable[i].ownerId == Oid.ownerId) {
2169 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2170 			if (plugintable[i].hPlugin != NULL) {
2171 				os_obtainmutex(plugintable[i].pluginMutex);
2172 #ifdef WIN32
2173 				PassFunc =
2174 				    (IMA_GetMaxBurstLengthPropertiesFn)
2175 				    GetProcAddress(plugintable[i].hPlugin,
2176 				    "IMA_GetMaxBurstLengthProperties");
2177 #else
2178 				PassFunc =
2179 				    (IMA_GetMaxBurstLengthPropertiesFn)
2180 				    dlsym(plugintable[i].hPlugin,
2181 				    "IMA_GetMaxBurstLengthProperties");
2182 #endif
2183 				if (PassFunc != NULL) {
2184 					status = PassFunc(Oid, pProps);
2185 				}
2186 				os_releasemutex(plugintable[i].pluginMutex);
2187 			}
2188 
2189 			break;
2190 		}
2191 	}
2192 	os_releasemutex(libMutex);
2193 	return (status);
2194 }
2195 
2196 
2197 /*
2198  * Gets the maximum receive data segment length properties
2199  * of the specified logical HBA.
2200  *
2201  * @param lhbaId The object ID of the logical HBA to
2202  *    get the max receive data
2203  *    segment length properties of.
2204  * @param pProps A pointer to an @ref IMA_MIN_MAX_VALUE
2205  *    structure allocated by the caller.
2206  *    On successful return this structure will contain the max
2207  *    receive data segment length properties of this LHBA.
2208  * @return An IMA_STATUS indicating if the operation
2209  *    was successful or if an error occurred.
2210  * @retval IMA_SUCCESS Returned if the max receive
2211  *    data segment length properties
2212  *    have been successfully retrieved.
2213  * @retval IMA_ERROR_INVALID_PARAMETER Returned if
2214  *    @a pProps is NULL or specifies a
2215  *    memory area to which data cannot be written.
2216  * @retval IMA_ERROR_INVALID_OBJECT_TYPE Returned if
2217  *    @a lhbaId does not specify any
2218  *    valid object type.
2219  * @retval IMA_ERROR_INCORRECT_OBJECT_TYPE Returned if
2220  *    a lhbaId does not specify a LHBA.
2221  * @retval IMA_ERROR_OBJECT_NOT_FOUND Returned if @a
2222  *    lhbaId does not specify a LHBA
2223  *    which is currently known to the system.
2224  */
2225 IMA_API IMA_STATUS IMA_GetMaxRecvDataSegmentLengthProperties(
2226     IMA_OID Oid,
2227     IMA_MIN_MAX_VALUE *pProps) {
2228 	IMA_GetMaxRecvDataSegmentLengthPropertiesFn PassFunc;
2229 	IMA_UINT i;
2230 	IMA_STATUS status;
2231 #define	IMA_GMRDSLPFN IMA_GetMaxRecvDataSegmentLengthPropertiesFn
2232 #define	IMA_GMRDSLP "IMA_GetMaxRecvDataSegmentLengthProperties"
2233 
2234 	if (number_of_plugins == -1)
2235 		InitLibrary();
2236 
2237 	if (pProps == NULL)
2238 		return (IMA_ERROR_INVALID_PARAMETER);
2239 
2240 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
2241 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
2242 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2243 
2244 	os_obtainmutex(libMutex);
2245 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2246 
2247 	for (i = 0; i < number_of_plugins; i++) {
2248 		if (plugintable[i].ownerId == Oid.ownerId) {
2249 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2250 			if (plugintable[i].hPlugin != NULL) {
2251 				os_obtainmutex(plugintable[i].pluginMutex);
2252 #ifdef WIN32
2253 				PassFunc =
2254 				    (IMA_GMRDSLPFN)
2255 				    GetProcAddress(plugintable[i].hPlugin,
2256 				    IMA_GMRDSLP);
2257 #else
2258 				PassFunc =
2259 				    (IMA_GMRDSLPFN)
2260 				    dlsym(plugintable[i].hPlugin,
2261 				    IMA_GMRDSLP);
2262 #endif
2263 
2264 				if (PassFunc != NULL) {
2265 					status = PassFunc(Oid, pProps);
2266 				}
2267 				os_releasemutex(plugintable[i].pluginMutex);
2268 			}
2269 
2270 			break;
2271 		}
2272 	}
2273 	os_releasemutex(libMutex);
2274 #undef IMA_GMRDSLPFN
2275 #undef IMA_GMRDSLP
2276 	return (status);
2277 }
2278 
2279 
2280 
2281 /* --------------------------------------------- */
2282 IMA_API IMA_STATUS IMA_PluginIOCtl(
2283     IMA_OID pluginOid,
2284     IMA_UINT command,
2285     const void *pInputBuffer,
2286     IMA_UINT inputBufferLength,
2287     void *pOutputBuffer,
2288     IMA_UINT *pOutputBufferLength) {
2289 	IMA_PluginIOCtlFn PassFunc;
2290 	IMA_UINT i;
2291 	IMA_STATUS status;
2292 
2293 	if (number_of_plugins == -1)
2294 		InitLibrary();
2295 
2296 	if (pInputBuffer == NULL || inputBufferLength == 0 ||
2297 	    pOutputBuffer == NULL || pOutputBufferLength == NULL ||
2298 	    *pOutputBufferLength == 0)
2299 		return (IMA_ERROR_INVALID_PARAMETER);
2300 
2301 	if (pluginOid.objectType != IMA_OBJECT_TYPE_PLUGIN)
2302 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2303 
2304 	os_obtainmutex(libMutex);
2305 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2306 
2307 	for (i = 0; i < number_of_plugins; i++) {
2308 		if (plugintable[i].ownerId == pluginOid.ownerId) {
2309 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2310 			if (plugintable[i].hPlugin != NULL) {
2311 				os_obtainmutex(plugintable[i].pluginMutex);
2312 #ifdef WIN32
2313 				PassFunc = (IMA_PluginIOCtlFn)
2314 				    GetProcAddress(plugintable[i].hPlugin,
2315 				    "IMA_PluginIOCtl");
2316 #else
2317 				PassFunc = (IMA_PluginIOCtlFn)
2318 				    dlsym(plugintable[i].hPlugin,
2319 				    "IMA_PluginIOCtl");
2320 #endif
2321 
2322 				if (PassFunc != NULL) {
2323 					status = PassFunc(
2324 					    pluginOid, command,
2325 					    pInputBuffer, inputBufferLength,
2326 					    pOutputBuffer, pOutputBufferLength);
2327 				}
2328 				os_releasemutex(plugintable[i].pluginMutex);
2329 			}
2330 
2331 			break;
2332 		}
2333 	}
2334 	os_releasemutex(libMutex);
2335 	return (status);
2336 }
2337 
2338 
2339 
2340 
2341 IMA_API IMA_STATUS IMA_GetNetworkPortalOidList(
2342     IMA_OID lnpId,
2343     IMA_OID_LIST **ppList) {
2344 	IMA_GetNetworkPortalOidListFn PassFunc;
2345 	IMA_FreeMemoryFn FreeFunc;
2346 	IMA_UINT i;
2347 	IMA_STATUS status;
2348 
2349 	if (number_of_plugins == -1)
2350 		InitLibrary();
2351 
2352 	if (ppList == NULL)
2353 		return (IMA_ERROR_INVALID_PARAMETER);
2354 
2355 	if (lnpId.objectType != IMA_OBJECT_TYPE_LNP)
2356 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2357 
2358 	os_obtainmutex(libMutex);
2359 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2360 
2361 	for (i = 0; i < number_of_plugins; i++) {
2362 		if (plugintable[i].ownerId == lnpId.ownerId) {
2363 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2364 			if (plugintable[i].hPlugin != NULL) {
2365 				os_obtainmutex(plugintable[i].pluginMutex);
2366 #ifdef WIN32
2367 				PassFunc = (IMA_GetNetworkPortalOidListFn)
2368 				    GetProcAddress(plugintable[i].hPlugin,
2369 				    "IMA_GetNetworkPortalOidList");
2370 #else
2371 				PassFunc = (IMA_GetNetworkPortalOidListFn)
2372 				    dlsym(plugintable[i].hPlugin,
2373 				    "IMA_GetNetworkPortalOidList");
2374 #endif
2375 
2376 				if (PassFunc != NULL) {
2377 					IMA_OID_LIST *ppOidList;
2378 					IMA_UINT listSize;
2379 					listSize = sizeof (IMA_OID_LIST);
2380 					status = PassFunc(lnpId, &ppOidList);
2381 					if (IMA_SUCCESS(status)) {
2382 
2383 						*ppList = (IMA_OID_LIST*)
2384 						    calloc(1,
2385 						    sizeof (IMA_OID_LIST)
2386 						    + (ppOidList->
2387 						    oidCount - 1)*
2388 						    sizeof (IMA_OID));
2389 
2390 						if ((*ppList) == NULL) {
2391 							return (EUOS_ERROR);
2392 						}
2393 						else
2394 							memcpy((*ppList),
2395 							    ppOidList,
2396 							    listSize
2397 							    + (ppOidList->
2398 							    oidCount - 1)*
2399 							    sizeof (IMA_OID));
2400 #ifdef WIN32
2401 						FreeFunc = (IMA_FreeMemoryFn)
2402 						    GetProcAddress(
2403 						    plugintable[i].hPlugin,
2404 						    "IMA_FreeMemory");
2405 #else
2406 						FreeFunc = (IMA_FreeMemoryFn)
2407 						    dlsym(
2408 						    plugintable[i].hPlugin,
2409 						    "IMA_FreeMemory");
2410 #endif
2411 						if (FreeFunc != NULL) {
2412 							FreeFunc(ppOidList);
2413 						}
2414 					}
2415 				}
2416 				os_releasemutex(plugintable[i].pluginMutex);
2417 			}
2418 
2419 			break;
2420 		}
2421 	}
2422 	os_releasemutex(libMutex);
2423 	return (status);
2424 }
2425 
2426 
2427 IMA_API IMA_STATUS IMA_SetFirstBurstLength(
2428     IMA_OID lhbaId,
2429     IMA_UINT firstBurstLength) {
2430 	IMA_SetFirstBurstLengthFn PassFunc;
2431 	IMA_UINT i;
2432 	IMA_STATUS status;
2433 
2434 	if (number_of_plugins == -1)
2435 		InitLibrary();
2436 
2437 	if (lhbaId.objectType != IMA_OBJECT_TYPE_LHBA &&
2438 	    lhbaId.objectType != IMA_OBJECT_TYPE_TARGET)
2439 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2440 
2441 	os_obtainmutex(libMutex);
2442 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2443 
2444 	for (i = 0; i < number_of_plugins; i++) {
2445 		if (plugintable[i].ownerId == lhbaId.ownerId) {
2446 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2447 			if (plugintable[i].hPlugin != NULL) {
2448 				os_obtainmutex(plugintable[i].pluginMutex);
2449 #ifdef WIN32
2450 				PassFunc = (IMA_SetFirstBurstLengthFn)
2451 				    GetProcAddress(plugintable[i].hPlugin,
2452 				    "IMA_SetFirstBurstLength");
2453 #else
2454 				PassFunc = (IMA_SetFirstBurstLengthFn)
2455 				    dlsym(
2456 				    plugintable[i].hPlugin,
2457 				    "IMA_SetFirstBurstLength");
2458 #endif
2459 
2460 				if (PassFunc != NULL) {
2461 					status = PassFunc(
2462 					    lhbaId, firstBurstLength);
2463 				}
2464 				os_releasemutex(plugintable[i].pluginMutex);
2465 			}
2466 
2467 			break;
2468 		}
2469 	}
2470 	os_releasemutex(libMutex);
2471 	return (status);
2472 }
2473 
2474 
2475 IMA_API IMA_STATUS IMA_SetMaxBurstLength(
2476     IMA_OID lhbaId,
2477     IMA_UINT maxBurstLength) {
2478 	IMA_SetMaxBurstLengthFn PassFunc;
2479 	IMA_UINT i;
2480 	IMA_STATUS status;
2481 
2482 	if (number_of_plugins == -1)
2483 		InitLibrary();
2484 
2485 	if (lhbaId.objectType != IMA_OBJECT_TYPE_LHBA &&
2486 	    lhbaId.objectType != IMA_OBJECT_TYPE_TARGET)
2487 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2488 
2489 	os_obtainmutex(libMutex);
2490 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2491 
2492 	for (i = 0; i < number_of_plugins; i++) {
2493 		if (plugintable[i].ownerId == lhbaId.ownerId) {
2494 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2495 			if (plugintable[i].hPlugin != NULL) {
2496 				os_obtainmutex(plugintable[i].pluginMutex);
2497 #ifdef WIN32
2498 				PassFunc = (IMA_SetMaxBurstLengthFn)
2499 				    GetProcAddress(plugintable[i].hPlugin,
2500 				    "IMA_SetMaxBurstLength");
2501 #else
2502 				PassFunc = (IMA_SetMaxBurstLengthFn)
2503 				    dlsym(plugintable[i].hPlugin,
2504 				    "IMA_SetMaxBurstLength");
2505 #endif
2506 
2507 				if (PassFunc != NULL) {
2508 					status = PassFunc(
2509 					    lhbaId, maxBurstLength);
2510 				}
2511 				os_releasemutex(plugintable[i].pluginMutex);
2512 			}
2513 
2514 			break;
2515 		}
2516 	}
2517 	os_releasemutex(libMutex);
2518 	return (status);
2519 }
2520 
2521 
2522 IMA_API IMA_STATUS IMA_SetMaxRecvDataSegmentLength(
2523     IMA_OID lhbaId,
2524     IMA_UINT maxRecvDataSegmentLength) {
2525 	IMA_SetMaxRecvDataSegmentLengthFn PassFunc;
2526 	IMA_UINT i;
2527 	IMA_STATUS status;
2528 
2529 	if (number_of_plugins == -1)
2530 		InitLibrary();
2531 
2532 	if (lhbaId.objectType != IMA_OBJECT_TYPE_LHBA &&
2533 	lhbaId.objectType != IMA_OBJECT_TYPE_TARGET)
2534 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2535 
2536 	os_obtainmutex(libMutex);
2537 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2538 
2539 	for (i = 0; i < number_of_plugins; i++) {
2540 		if (plugintable[i].ownerId == lhbaId.ownerId) {
2541 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2542 			if (plugintable[i].hPlugin != NULL) {
2543 				os_obtainmutex(plugintable[i].pluginMutex);
2544 #ifdef WIN32
2545 				PassFunc =
2546 				    (IMA_SetMaxRecvDataSegmentLengthFn)
2547 				    GetProcAddress(plugintable[i].hPlugin,
2548 				    "IMA_SetMaxRecvDataSegmentLength");
2549 #else
2550 				PassFunc =
2551 				    (IMA_SetMaxRecvDataSegmentLengthFn)
2552 				    dlsym(plugintable[i].hPlugin,
2553 				    "IMA_SetMaxRecvDataSegmentLength");
2554 #endif
2555 
2556 				if (PassFunc != NULL) {
2557 					status = PassFunc(
2558 					    lhbaId,
2559 					    maxRecvDataSegmentLength);
2560 				}
2561 				os_releasemutex(plugintable[i].pluginMutex);
2562 			}
2563 
2564 			break;
2565 		}
2566 	}
2567 	os_releasemutex(libMutex);
2568 	return (status);
2569 }
2570 
2571 
2572 IMA_API IMA_STATUS IMA_GetMaxConnectionsProperties(
2573     IMA_OID Oid,
2574     IMA_MIN_MAX_VALUE *pProps) {
2575 	IMA_GetMaxConnectionsPropertiesFn PassFunc;
2576 	IMA_UINT i;
2577 	IMA_STATUS status;
2578 
2579 	if (number_of_plugins == -1)
2580 		InitLibrary();
2581 
2582 	if (pProps == NULL)
2583 		return (IMA_ERROR_INVALID_PARAMETER);
2584 
2585 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
2586 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
2587 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2588 
2589 	os_obtainmutex(libMutex);
2590 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2591 
2592 	for (i = 0; i < number_of_plugins; i++) {
2593 		if (plugintable[i].ownerId == Oid.ownerId) {
2594 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2595 			if (plugintable[i].hPlugin != NULL) {
2596 				os_obtainmutex(plugintable[i].pluginMutex);
2597 #ifdef WIN32
2598 				PassFunc =
2599 				    (IMA_GetMaxConnectionsPropertiesFn)
2600 				    GetProcAddress(plugintable[i].hPlugin,
2601 				    "IMA_GetMaxConnectionsProperties");
2602 #else
2603 				PassFunc =
2604 				    (IMA_GetMaxConnectionsPropertiesFn)
2605 				    dlsym(plugintable[i].hPlugin,
2606 				    "IMA_GetMaxConnectionsProperties");
2607 #endif
2608 
2609 				if (PassFunc != NULL) {
2610 					status = PassFunc(Oid, pProps);
2611 				}
2612 				os_releasemutex(plugintable[i].pluginMutex);
2613 			}
2614 
2615 			break;
2616 		}
2617 	}
2618 	os_releasemutex(libMutex);
2619 	return (status);
2620 }
2621 
2622 
2623 IMA_API IMA_STATUS IMA_SetMaxConnections(
2624     IMA_OID lhbaId,
2625     IMA_UINT maxConnections) {
2626 	IMA_SetMaxConnectionsFn PassFunc;
2627 	IMA_UINT i;
2628 	IMA_STATUS status;
2629 
2630 	if (number_of_plugins == -1)
2631 		InitLibrary();
2632 
2633 	if (lhbaId.objectType != IMA_OBJECT_TYPE_LHBA &&
2634 	    lhbaId.objectType != IMA_OBJECT_TYPE_TARGET)
2635 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2636 
2637 	os_obtainmutex(libMutex);
2638 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2639 
2640 	for (i = 0; i < number_of_plugins; i++) {
2641 		if (plugintable[i].ownerId == lhbaId.ownerId) {
2642 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2643 			if (plugintable[i].hPlugin != NULL) {
2644 				os_obtainmutex(plugintable[i].pluginMutex);
2645 #ifdef WIN32
2646 				PassFunc = (IMA_SetMaxConnectionsFn)
2647 				    GetProcAddress(plugintable[i].hPlugin,
2648 				    "IMA_SetMaxConnections");
2649 #else
2650 				PassFunc = (IMA_SetMaxConnectionsFn)
2651 				    dlsym(plugintable[i].hPlugin,
2652 				    "IMA_SetMaxConnections");
2653 #endif
2654 
2655 				if (PassFunc != NULL) {
2656 					status = PassFunc(
2657 					    lhbaId, maxConnections);
2658 				}
2659 				os_releasemutex(plugintable[i].pluginMutex);
2660 			}
2661 
2662 			break;
2663 		}
2664 	}
2665 	os_releasemutex(libMutex);
2666 	return (status);
2667 }
2668 
2669 
2670 IMA_API IMA_STATUS IMA_GetDefaultTime2RetainProperties(
2671     IMA_OID lhbaId,
2672     IMA_MIN_MAX_VALUE *pProps) {
2673 	IMA_GetDefaultTime2RetainPropertiesFn PassFunc;
2674 	IMA_UINT i;
2675 	IMA_STATUS status;
2676 
2677 	if (number_of_plugins == -1)
2678 		InitLibrary();
2679 
2680 	if (pProps == NULL)
2681 		return (IMA_ERROR_INVALID_PARAMETER);
2682 
2683 	if (lhbaId.objectType != IMA_OBJECT_TYPE_LHBA &&
2684 	    lhbaId.objectType != IMA_OBJECT_TYPE_TARGET)
2685 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2686 
2687 	os_obtainmutex(libMutex);
2688 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2689 
2690 	for (i = 0; i < number_of_plugins; i++) {
2691 		if (plugintable[i].ownerId == lhbaId.ownerId) {
2692 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2693 			if (plugintable[i].hPlugin != NULL) {
2694 				os_obtainmutex(plugintable[i].pluginMutex);
2695 #ifdef WIN32
2696 				PassFunc =
2697 				    (IMA_GetDefaultTime2RetainPropertiesFn)
2698 				    GetProcAddress(plugintable[i].hPlugin,
2699 				    "IMA_GetDefaultTime2RetainProperties");
2700 #else
2701 				PassFunc =
2702 				    (IMA_GetDefaultTime2RetainPropertiesFn)
2703 				    dlsym(plugintable[i].hPlugin,
2704 				    "IMA_GetDefaultTime2RetainProperties");
2705 #endif
2706 
2707 				if (PassFunc != NULL) {
2708 					status = PassFunc(lhbaId, pProps);
2709 				}
2710 				os_releasemutex(plugintable[i].pluginMutex);
2711 			}
2712 
2713 			break;
2714 		}
2715 	}
2716 	os_releasemutex(libMutex);
2717 	return (status);
2718 }
2719 
2720 
2721 IMA_API IMA_STATUS IMA_SetDefaultTime2Retain(
2722     IMA_OID lhbaId,
2723     IMA_UINT defaultTime2Retain) {
2724 	IMA_SetDefaultTime2RetainFn PassFunc;
2725 	IMA_UINT i;
2726 	IMA_STATUS status;
2727 
2728 	if (number_of_plugins == -1)
2729 		InitLibrary();
2730 
2731 	if (lhbaId.objectType != IMA_OBJECT_TYPE_LHBA &&
2732 	    lhbaId.objectType != IMA_OBJECT_TYPE_TARGET)
2733 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2734 
2735 	os_obtainmutex(libMutex);
2736 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2737 
2738 	for (i = 0; i < number_of_plugins; i++) {
2739 		if (plugintable[i].ownerId == lhbaId.ownerId) {
2740 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2741 			if (plugintable[i].hPlugin != NULL) {
2742 				os_obtainmutex(plugintable[i].pluginMutex);
2743 #ifdef WIN32
2744 				PassFunc =
2745 				    (IMA_SetDefaultTime2RetainFn)
2746 				    GetProcAddress(plugintable[i].hPlugin,
2747 				    "IMA_SetDefaultTime2Retain");
2748 #else
2749 				PassFunc =
2750 				    (IMA_SetDefaultTime2RetainFn)
2751 				    dlsym(plugintable[i].hPlugin,
2752 				    "IMA_SetDefaultTime2Retain");
2753 #endif
2754 
2755 				if (PassFunc != NULL) {
2756 					status = PassFunc(
2757 					    lhbaId, defaultTime2Retain);
2758 				}
2759 				os_releasemutex(plugintable[i].pluginMutex);
2760 			}
2761 
2762 			break;
2763 		}
2764 	}
2765 	os_releasemutex(libMutex);
2766 	return (status);
2767 }
2768 
2769 
2770 IMA_API IMA_STATUS IMA_GetDefaultTime2WaitProperties(
2771     IMA_OID lhbaId,
2772     IMA_MIN_MAX_VALUE *pProps) {
2773 	IMA_GetDefaultTime2WaitPropertiesFn PassFunc;
2774 	IMA_UINT i;
2775 	IMA_STATUS status;
2776 
2777 	if (number_of_plugins == -1)
2778 		InitLibrary();
2779 
2780 	if (pProps == NULL)
2781 		return (IMA_ERROR_INVALID_PARAMETER);
2782 
2783 	if (lhbaId.objectType != IMA_OBJECT_TYPE_LHBA &&
2784 	    lhbaId.objectType != IMA_OBJECT_TYPE_TARGET)
2785 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2786 
2787 	os_obtainmutex(libMutex);
2788 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2789 
2790 	for (i = 0; i < number_of_plugins; i++) {
2791 		if (plugintable[i].ownerId == lhbaId.ownerId) {
2792 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2793 			if (plugintable[i].hPlugin != NULL) {
2794 				os_obtainmutex(plugintable[i].pluginMutex);
2795 #ifdef WIN32
2796 				PassFunc =
2797 				    (IMA_GetDefaultTime2WaitPropertiesFn)
2798 				    GetProcAddress(plugintable[i].hPlugin,
2799 				    "IMA_GetDefaultTime2WaitProperties");
2800 #else
2801 				PassFunc =
2802 				    (IMA_GetDefaultTime2WaitPropertiesFn)
2803 				    dlsym(plugintable[i].hPlugin,
2804 				    "IMA_GetDefaultTime2WaitProperties");
2805 #endif
2806 
2807 				if (PassFunc != NULL) {
2808 					status = PassFunc(lhbaId, pProps);
2809 				}
2810 				os_releasemutex(plugintable[i].pluginMutex);
2811 			}
2812 
2813 			break;
2814 		}
2815 	}
2816 	os_releasemutex(libMutex);
2817 	return (status);
2818 }
2819 
2820 
2821 IMA_API IMA_STATUS IMA_SetDefaultTime2Wait(
2822     IMA_OID lhbaId,
2823     IMA_UINT defaultTime2Wait) {
2824 	IMA_SetDefaultTime2WaitFn PassFunc;
2825 	IMA_UINT i;
2826 	IMA_STATUS status;
2827 
2828 	if (number_of_plugins == -1)
2829 		InitLibrary();
2830 
2831 	if (lhbaId.objectType != IMA_OBJECT_TYPE_LHBA &&
2832 	    lhbaId.objectType != IMA_OBJECT_TYPE_TARGET)
2833 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2834 
2835 	os_obtainmutex(libMutex);
2836 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2837 
2838 	for (i = 0; i < number_of_plugins; i++) {
2839 		if (plugintable[i].ownerId == lhbaId.ownerId) {
2840 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2841 			if (plugintable[i].hPlugin != NULL) {
2842 				os_obtainmutex(plugintable[i].pluginMutex);
2843 #ifdef WIN32
2844 				PassFunc =
2845 				    (IMA_SetDefaultTime2WaitFn)
2846 				    GetProcAddress(plugintable[i].hPlugin,
2847 				    "IMA_SetDefaultTime2Wait");
2848 #else
2849 				PassFunc =
2850 				    (IMA_SetDefaultTime2WaitFn)
2851 				    dlsym(plugintable[i].hPlugin,
2852 				    "IMA_SetDefaultTime2Wait");
2853 #endif
2854 
2855 				if (PassFunc != NULL) {
2856 					status = PassFunc(
2857 					    lhbaId, defaultTime2Wait);
2858 				}
2859 				os_releasemutex(plugintable[i].pluginMutex);
2860 			}
2861 
2862 			break;
2863 		}
2864 	}
2865 	os_releasemutex(libMutex);
2866 	return (status);
2867 }
2868 
2869 
2870 IMA_API IMA_STATUS IMA_GetMaxOutstandingR2TProperties(
2871     IMA_OID Oid,
2872     IMA_MIN_MAX_VALUE *pProps) {
2873 	IMA_GetMaxOutstandingR2TPropertiesFn PassFunc;
2874 	IMA_UINT i;
2875 	IMA_STATUS status;
2876 
2877 	if (number_of_plugins == -1)
2878 		InitLibrary();
2879 
2880 	if (pProps == NULL)
2881 		return (IMA_ERROR_INVALID_PARAMETER);
2882 
2883 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
2884 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
2885 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2886 
2887 	os_obtainmutex(libMutex);
2888 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2889 
2890 	for (i = 0; i < number_of_plugins; i++) {
2891 		if (plugintable[i].ownerId == Oid.ownerId) {
2892 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2893 			if (plugintable[i].hPlugin != NULL) {
2894 				os_obtainmutex(plugintable[i].pluginMutex);
2895 #ifdef WIN32
2896 				PassFunc =
2897 				    (IMA_GetMaxOutstandingR2TPropertiesFn)
2898 				    GetProcAddress(plugintable[i].hPlugin,
2899 				    "IMA_GetMaxOutstandingR2TProperties");
2900 #else
2901 				PassFunc =
2902 				    (IMA_GetMaxOutstandingR2TPropertiesFn)
2903 				    dlsym(plugintable[i].hPlugin,
2904 				    "IMA_GetMaxOutstandingR2TProperties");
2905 #endif
2906 
2907 				if (PassFunc != NULL) {
2908 					status = PassFunc(Oid, pProps);
2909 				}
2910 				os_releasemutex(plugintable[i].pluginMutex);
2911 			}
2912 
2913 			break;
2914 		}
2915 	}
2916 	os_releasemutex(libMutex);
2917 	return (status);
2918 }
2919 
2920 
2921 IMA_API IMA_STATUS IMA_SetMaxOutstandingR2T(
2922     IMA_OID lhbaId,
2923     IMA_UINT maxOutstandingR2T) {
2924 	IMA_SetMaxOutstandingR2TFn PassFunc;
2925 	IMA_UINT i;
2926 	IMA_STATUS status;
2927 
2928 	if (number_of_plugins == -1)
2929 		InitLibrary();
2930 
2931 	if (lhbaId.objectType != IMA_OBJECT_TYPE_LHBA &&
2932 	    lhbaId.objectType != IMA_OBJECT_TYPE_TARGET)
2933 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2934 
2935 	os_obtainmutex(libMutex);
2936 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2937 
2938 	for (i = 0; i < number_of_plugins; i++) {
2939 		if (plugintable[i].ownerId == lhbaId.ownerId) {
2940 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2941 			if (plugintable[i].hPlugin != NULL) {
2942 				os_obtainmutex(plugintable[i].pluginMutex);
2943 #ifdef WIN32
2944 				PassFunc =
2945 				    (IMA_SetMaxOutstandingR2TFn)
2946 				    GetProcAddress(plugintable[i].hPlugin,
2947 				    "IMA_SetMaxOutstandingR2T");
2948 #else
2949 				PassFunc =
2950 				    (IMA_SetMaxOutstandingR2TFn)
2951 				    dlsym(plugintable[i].hPlugin,
2952 				    "IMA_SetMaxOutstandingR2T");
2953 #endif
2954 
2955 				if (PassFunc != NULL) {
2956 					status = PassFunc(
2957 					    lhbaId, maxOutstandingR2T);
2958 				}
2959 				os_releasemutex(plugintable[i].pluginMutex);
2960 			}
2961 
2962 			break;
2963 		}
2964 	}
2965 	os_releasemutex(libMutex);
2966 	return (status);
2967 }
2968 
2969 
2970 IMA_API IMA_STATUS IMA_GetErrorRecoveryLevelProperties(
2971     IMA_OID Oid,
2972     IMA_MIN_MAX_VALUE *pProps) {
2973 	IMA_GetMaxOutstandingR2TPropertiesFn PassFunc;
2974 	IMA_UINT i;
2975 	IMA_STATUS status;
2976 
2977 	if (number_of_plugins == -1)
2978 		InitLibrary();
2979 
2980 	if (pProps == NULL)
2981 		return (IMA_ERROR_INVALID_PARAMETER);
2982 
2983 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
2984 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
2985 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2986 
2987 	os_obtainmutex(libMutex);
2988 	status = IMA_ERROR_OBJECT_NOT_FOUND;
2989 
2990 	for (i = 0; i < number_of_plugins; i++) {
2991 		if (plugintable[i].ownerId == Oid.ownerId) {
2992 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2993 			if (plugintable[i].hPlugin != NULL) {
2994 				os_obtainmutex(plugintable[i].pluginMutex);
2995 #ifdef WIN32
2996 				PassFunc =
2997 				    (IMA_GetErrorRecoveryLevelPropertiesFn)
2998 				    GetProcAddress(plugintable[i].hPlugin,
2999 				    "IMA_GetErrorRecoveryLevelProperties");
3000 #else
3001 				PassFunc =
3002 				    (IMA_GetErrorRecoveryLevelPropertiesFn)
3003 				    dlsym(plugintable[i].hPlugin,
3004 				    "IMA_GetErrorRecoveryLevelProperties");
3005 #endif
3006 
3007 				if (PassFunc != NULL) {
3008 					status = PassFunc(Oid, pProps);
3009 				}
3010 				os_releasemutex(plugintable[i].pluginMutex);
3011 			}
3012 
3013 			break;
3014 		}
3015 	}
3016 	os_releasemutex(libMutex);
3017 	return (status);
3018 }
3019 
3020 
3021 IMA_API IMA_STATUS IMA_SetErrorRecoveryLevel(
3022     IMA_OID Oid,
3023     IMA_UINT errorRecoveryLevel) {
3024 	IMA_SetErrorRecoveryLevelFn PassFunc;
3025 	IMA_UINT i;
3026 	IMA_STATUS status;
3027 
3028 	if (number_of_plugins == -1)
3029 		InitLibrary();
3030 
3031 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
3032 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
3033 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3034 
3035 	os_obtainmutex(libMutex);
3036 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3037 
3038 	for (i = 0; i < number_of_plugins; i++) {
3039 		if (plugintable[i].ownerId == Oid.ownerId) {
3040 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3041 			if (plugintable[i].hPlugin != NULL) {
3042 				os_obtainmutex(plugintable[i].pluginMutex);
3043 #ifdef WIN32
3044 				PassFunc =
3045 				    (IMA_SetErrorRecoveryLevelFn)
3046 				    GetProcAddress(plugintable[i].hPlugin,
3047 				    "IMA_SetErrorRecoveryLevel");
3048 #else
3049 				PassFunc =
3050 				    (IMA_SetErrorRecoveryLevelFn)
3051 				    dlsym(plugintable[i].hPlugin,
3052 				    "IMA_SetErrorRecoveryLevel");
3053 #endif
3054 
3055 				if (PassFunc != NULL) {
3056 					status = PassFunc(
3057 					    Oid, errorRecoveryLevel);
3058 				}
3059 				os_releasemutex(plugintable[i].pluginMutex);
3060 			}
3061 
3062 			break;
3063 		}
3064 	}
3065 	os_releasemutex(libMutex);
3066 	return (status);
3067 }
3068 
3069 
3070 IMA_API IMA_STATUS IMA_GetInitialR2TProperties(
3071     IMA_OID Oid,
3072     IMA_BOOL_VALUE *pProps) {
3073 	IMA_GetInitialR2TPropertiesFn PassFunc;
3074 	IMA_UINT i;
3075 	IMA_STATUS status;
3076 
3077 	if (number_of_plugins == -1)
3078 		InitLibrary();
3079 
3080 	if (pProps == NULL)
3081 		return (IMA_ERROR_INVALID_PARAMETER);
3082 
3083 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
3084 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
3085 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3086 
3087 	os_obtainmutex(libMutex);
3088 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3089 
3090 	for (i = 0; i < number_of_plugins; i++) {
3091 		if (plugintable[i].ownerId == Oid.ownerId) {
3092 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3093 			if (plugintable[i].hPlugin != NULL) {
3094 				os_obtainmutex(plugintable[i].pluginMutex);
3095 #ifdef WIN32
3096 				PassFunc =
3097 				    (IMA_GetInitialR2TPropertiesFn)
3098 				    GetProcAddress(plugintable[i].hPlugin,
3099 				    "IMA_GetInitialR2TProperties");
3100 #else
3101 				PassFunc =
3102 				    (IMA_GetInitialR2TPropertiesFn)
3103 				    dlsym(plugintable[i].hPlugin,
3104 				    "IMA_GetInitialR2TProperties");
3105 #endif
3106 
3107 				if (PassFunc != NULL) {
3108 					status = PassFunc(Oid, pProps);
3109 				}
3110 				os_releasemutex(plugintable[i].pluginMutex);
3111 			}
3112 
3113 			break;
3114 		}
3115 	}
3116 	os_releasemutex(libMutex);
3117 	return (status);
3118 }
3119 
3120 
3121 IMA_API IMA_STATUS IMA_SetInitialR2T(
3122     IMA_OID Oid,
3123     IMA_BOOL initialR2T)
3124 {
3125 	IMA_SetInitialR2TFn PassFunc;
3126 	IMA_UINT i;
3127 	IMA_STATUS status;
3128 
3129 	if (number_of_plugins == -1)
3130 		InitLibrary();
3131 
3132 	if (initialR2T != IMA_TRUE &&
3133 	    initialR2T != IMA_FALSE)
3134 		return (IMA_ERROR_INVALID_PARAMETER);
3135 
3136 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
3137 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
3138 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3139 
3140 	os_obtainmutex(libMutex);
3141 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3142 
3143 	for (i = 0; i < number_of_plugins; i++) {
3144 		if (plugintable[i].ownerId == Oid.ownerId) {
3145 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3146 			if (plugintable[i].hPlugin != NULL) {
3147 				os_obtainmutex(plugintable[i].pluginMutex);
3148 #ifdef WIN32
3149 				PassFunc =
3150 				    (IMA_SetInitialR2TFn) GetProcAddress(
3151 				    plugintable[i].hPlugin,
3152 				    "IMA_SetInitialR2T");
3153 #else
3154 				PassFunc =
3155 				    (IMA_SetInitialR2TFn)
3156 				    dlsym(plugintable[i].hPlugin,
3157 				    "IMA_SetInitialR2T");
3158 #endif
3159 
3160 				if (PassFunc != NULL) {
3161 					status = PassFunc(Oid, initialR2T);
3162 				}
3163 				os_releasemutex(plugintable[i].pluginMutex);
3164 			}
3165 
3166 			break;
3167 		}
3168 	}
3169 	os_releasemutex(libMutex);
3170 	return (status);
3171 }
3172 
3173 
3174 IMA_API IMA_STATUS IMA_GetImmediateDataProperties(
3175     IMA_OID Oid,
3176     IMA_BOOL_VALUE *pProps) {
3177 	IMA_GetImmediateDataPropertiesFn PassFunc;
3178 	IMA_UINT i;
3179 	IMA_STATUS status;
3180 
3181 	if (number_of_plugins == -1)
3182 		InitLibrary();
3183 
3184 	if (pProps == NULL)
3185 		return (IMA_ERROR_INVALID_PARAMETER);
3186 
3187 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
3188 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
3189 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3190 
3191 	os_obtainmutex(libMutex);
3192 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3193 
3194 	for (i = 0; i < number_of_plugins; i++) {
3195 		if (plugintable[i].ownerId == Oid.ownerId) {
3196 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3197 			if (plugintable[i].hPlugin != NULL) {
3198 				os_obtainmutex(plugintable[i].pluginMutex);
3199 #ifdef WIN32
3200 				PassFunc =
3201 				    (IMA_GetImmediateDataPropertiesFn)
3202 				    GetProcAddress(plugintable[i].hPlugin,
3203 				    "IMA_GetImmediateDataProperties");
3204 #else
3205 				PassFunc =
3206 				    (IMA_GetImmediateDataPropertiesFn)
3207 				    dlsym(plugintable[i].hPlugin,
3208 				    "IMA_GetImmediateDataProperties");
3209 #endif
3210 
3211 				if (PassFunc != NULL) {
3212 					status = PassFunc(Oid, pProps);
3213 				}
3214 				os_releasemutex(plugintable[i].pluginMutex);
3215 			}
3216 
3217 			break;
3218 		}
3219 	}
3220 	os_releasemutex(libMutex);
3221 	return (status);
3222 }
3223 
3224 
3225 IMA_API IMA_STATUS IMA_SetImmediateData(
3226     IMA_OID Oid,
3227     IMA_BOOL immediateData) {
3228 	IMA_SetImmediateDataFn PassFunc;
3229 	IMA_UINT i;
3230 	IMA_STATUS status;
3231 
3232 	if (number_of_plugins == -1)
3233 		InitLibrary();
3234 
3235 	if (immediateData != IMA_TRUE &&
3236 	    immediateData != IMA_FALSE)
3237 		return (IMA_ERROR_INVALID_PARAMETER);
3238 
3239 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
3240 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
3241 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3242 
3243 	os_obtainmutex(libMutex);
3244 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3245 
3246 	for (i = 0; i < number_of_plugins; i++) {
3247 		if (plugintable[i].ownerId == Oid.ownerId) {
3248 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3249 			if (plugintable[i].hPlugin != NULL) {
3250 				os_obtainmutex(plugintable[i].pluginMutex);
3251 #ifdef WIN32
3252 				PassFunc =
3253 				    (IMA_SetImmediateDataFn)
3254 				    GetProcAddress(plugintable[i].hPlugin,
3255 				    "IMA_SetImmediateData");
3256 #else
3257 				PassFunc =
3258 				    (IMA_SetImmediateDataFn)
3259 				    dlsym(plugintable[i].hPlugin,
3260 				    "IMA_SetImmediateData");
3261 #endif
3262 
3263 				if (PassFunc != NULL) {
3264 					status = PassFunc(Oid, immediateData);
3265 				}
3266 				os_releasemutex(plugintable[i].pluginMutex);
3267 			}
3268 
3269 			break;
3270 		}
3271 	}
3272 	os_releasemutex(libMutex);
3273 	return (status);
3274 }
3275 
3276 
3277 IMA_API IMA_STATUS IMA_GetDataPduInOrderProperties(
3278     IMA_OID Oid,
3279     IMA_BOOL_VALUE *pProps) {
3280 	IMA_GetDataPduInOrderPropertiesFn PassFunc;
3281 	IMA_UINT i;
3282 	IMA_STATUS status;
3283 
3284 	if (number_of_plugins == -1)
3285 		InitLibrary();
3286 
3287 	if (pProps == NULL)
3288 		return (IMA_ERROR_INVALID_PARAMETER);
3289 
3290 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
3291 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
3292 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3293 
3294 	os_obtainmutex(libMutex);
3295 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3296 
3297 	for (i = 0; i < number_of_plugins; i++) {
3298 		if (plugintable[i].ownerId == Oid.ownerId) {
3299 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3300 			if (plugintable[i].hPlugin != NULL) {
3301 				os_obtainmutex(plugintable[i].pluginMutex);
3302 #ifdef WIN32
3303 				PassFunc =
3304 				    (IMA_GetDataPduInOrderPropertiesFn)
3305 				    GetProcAddress(plugintable[i].hPlugin,
3306 				    "IMA_GetDataPduInOrderProperties");
3307 #else
3308 				PassFunc =
3309 				    (IMA_GetDataPduInOrderPropertiesFn)
3310 				    dlsym(plugintable[i].hPlugin,
3311 				    "IMA_GetDataPduInOrderProperties");
3312 #endif
3313 
3314 				if (PassFunc != NULL) {
3315 					status = PassFunc(Oid, pProps);
3316 				}
3317 				os_releasemutex(plugintable[i].pluginMutex);
3318 			}
3319 
3320 			break;
3321 		}
3322 	}
3323 	os_releasemutex(libMutex);
3324 	return (status);
3325 }
3326 
3327 
3328 IMA_API IMA_STATUS IMA_SetDataPduInOrder(
3329     IMA_OID Oid,
3330     IMA_BOOL dataPduInOrder) {
3331 	IMA_SetDataPduInOrderFn PassFunc;
3332 	IMA_UINT i;
3333 	IMA_STATUS status;
3334 
3335 	if (number_of_plugins == -1)
3336 		InitLibrary();
3337 
3338 	if (dataPduInOrder != IMA_TRUE &&
3339 	    dataPduInOrder != IMA_FALSE)
3340 		return (IMA_ERROR_INVALID_PARAMETER);
3341 
3342 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
3343 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
3344 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3345 
3346 	os_obtainmutex(libMutex);
3347 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3348 
3349 	for (i = 0; i < number_of_plugins; i++) {
3350 		if (plugintable[i].ownerId == Oid.ownerId) {
3351 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3352 			if (plugintable[i].hPlugin != NULL) {
3353 				os_obtainmutex(plugintable[i].pluginMutex);
3354 #ifdef WIN32
3355 				PassFunc =
3356 				    (IMA_SetDataPduInOrderFn)
3357 				    GetProcAddress(plugintable[i].hPlugin,
3358 				    "IMA_SetDataPduInOrder");
3359 #else
3360 				PassFunc =
3361 				    (IMA_SetDataPduInOrderFn)
3362 				    dlsym(plugintable[i].hPlugin,
3363 				    "IMA_SetDataPduInOrder");
3364 #endif
3365 
3366 				if (PassFunc != NULL) {
3367 					status = PassFunc(Oid, dataPduInOrder);
3368 				}
3369 				os_releasemutex(plugintable[i].pluginMutex);
3370 			}
3371 
3372 			break;
3373 		}
3374 	}
3375 	os_releasemutex(libMutex);
3376 	return (status);
3377 }
3378 
3379 
3380 IMA_API IMA_STATUS IMA_GetDataSequenceInOrderProperties(
3381     IMA_OID Oid,
3382     IMA_BOOL_VALUE *pProps) {
3383 	IMA_GetDataSequenceInOrderPropertiesFn PassFunc;
3384 	IMA_UINT i;
3385 	IMA_STATUS status;
3386 
3387 	if (number_of_plugins == -1)
3388 		InitLibrary();
3389 
3390 	if (pProps == NULL)
3391 		return (IMA_ERROR_INVALID_PARAMETER);
3392 
3393 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
3394 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
3395 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3396 
3397 	os_obtainmutex(libMutex);
3398 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3399 
3400 	for (i = 0; i < number_of_plugins; i++) {
3401 		if (plugintable[i].ownerId == Oid.ownerId) {
3402 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3403 			if (plugintable[i].hPlugin != NULL) {
3404 				os_obtainmutex(plugintable[i].pluginMutex);
3405 #ifdef WIN32
3406 				PassFunc =
3407 				    (IMA_GetDataSequenceInOrderPropertiesFn)
3408 				    GetProcAddress(plugintable[i].hPlugin,
3409 				    "IMA_GetDataSequenceInOrderProperties");
3410 #else
3411 				PassFunc =
3412 				    (IMA_GetDataSequenceInOrderPropertiesFn)
3413 				    dlsym(plugintable[i].hPlugin,
3414 				    "IMA_GetDataSequenceInOrderProperties");
3415 #endif
3416 
3417 				if (PassFunc != NULL) {
3418 					status = PassFunc(Oid, pProps);
3419 				}
3420 				os_releasemutex(plugintable[i].pluginMutex);
3421 			}
3422 
3423 			break;
3424 		}
3425 	}
3426 	os_releasemutex(libMutex);
3427 	return (status);
3428 }
3429 
3430 
3431 IMA_API IMA_STATUS IMA_SetDataSequenceInOrder(
3432     IMA_OID Oid,
3433     IMA_BOOL dataSequenceInOrder) {
3434 	IMA_SetDataSequenceInOrderFn PassFunc;
3435 	IMA_UINT i;
3436 	IMA_STATUS status;
3437 
3438 	if (number_of_plugins == -1)
3439 		InitLibrary();
3440 
3441 	if (dataSequenceInOrder != IMA_TRUE &&
3442 	    dataSequenceInOrder != IMA_FALSE)
3443 		return (IMA_ERROR_INVALID_PARAMETER);
3444 
3445 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
3446 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
3447 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3448 
3449 	os_obtainmutex(libMutex);
3450 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3451 
3452 	for (i = 0; i < number_of_plugins; i++) {
3453 		if (plugintable[i].ownerId == Oid.ownerId) {
3454 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3455 			if (plugintable[i].hPlugin != NULL) {
3456 				os_obtainmutex(plugintable[i].pluginMutex);
3457 #ifdef WIN32
3458 				PassFunc =
3459 				    (IMA_SetDataSequenceInOrderFn)
3460 				    GetProcAddress(plugintable[i].hPlugin,
3461 				    "IMA_SetDataSequenceInOrder");
3462 #else
3463 				PassFunc =
3464 				    (IMA_SetDataSequenceInOrderFn)
3465 				    dlsym(plugintable[i].hPlugin,
3466 				    "IMA_SetDataSequenceInOrder");
3467 #endif
3468 
3469 				if (PassFunc != NULL) {
3470 					status = PassFunc(
3471 					    Oid, dataSequenceInOrder);
3472 				}
3473 				os_releasemutex(plugintable[i].pluginMutex);
3474 			}
3475 
3476 			break;
3477 		}
3478 	}
3479 	os_releasemutex(libMutex);
3480 	return (status);
3481 }
3482 
3483 
3484 IMA_API IMA_STATUS IMA_SetStatisticsCollection(
3485     IMA_OID Oid,
3486     IMA_BOOL enableStatisticsCollection) {
3487 	IMA_SetStatisticsCollectionFn PassFunc;
3488 	IMA_UINT i;
3489 	IMA_STATUS status;
3490 
3491 	if (number_of_plugins == -1)
3492 		InitLibrary();
3493 
3494 	if (enableStatisticsCollection != IMA_TRUE &&
3495 	    enableStatisticsCollection != IMA_FALSE)
3496 		return (IMA_ERROR_INVALID_PARAMETER);
3497 
3498 	if (Oid.objectType != IMA_OBJECT_TYPE_PHBA &&
3499 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
3500 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3501 
3502 	os_obtainmutex(libMutex);
3503 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3504 
3505 	for (i = 0; i < number_of_plugins; i++) {
3506 		if (plugintable[i].ownerId == Oid.ownerId) {
3507 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3508 			if (plugintable[i].hPlugin != NULL) {
3509 				os_obtainmutex(plugintable[i].pluginMutex);
3510 #ifdef WIN32
3511 				PassFunc =
3512 				    (IMA_SetStatisticsCollectionFn)
3513 				    GetProcAddress(plugintable[i].hPlugin,
3514 				    "IMA_SetStatisticsCollection");
3515 #else
3516 				PassFunc =
3517 				    (IMA_SetStatisticsCollectionFn)
3518 				    dlsym(plugintable[i].hPlugin,
3519 				    "IMA_SetStatisticsCollection");
3520 #endif
3521 
3522 				if (PassFunc != NULL) {
3523 					status = PassFunc(
3524 					Oid, enableStatisticsCollection);
3525 				}
3526 				os_releasemutex(plugintable[i].pluginMutex);
3527 			}
3528 
3529 			break;
3530 		}
3531 	}
3532 	os_releasemutex(libMutex);
3533 	return (status);
3534 }
3535 
3536 
3537 IMA_API IMA_STATUS IMA_GetNetworkPortStatus(
3538     IMA_OID portOid,
3539     IMA_NETWORK_PORT_STATUS *pStatus) {
3540 	IMA_GetNetworkPortStatusFn PassFunc;
3541 	IMA_UINT i;
3542 	IMA_STATUS status;
3543 
3544 	if (number_of_plugins == -1)
3545 		InitLibrary();
3546 
3547 	if (pStatus == NULL)
3548 		return (IMA_ERROR_INVALID_PARAMETER);
3549 
3550 	if (portOid.objectType != IMA_OBJECT_TYPE_PNP &&
3551 	    portOid.objectType != IMA_OBJECT_TYPE_LNP)
3552 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3553 
3554 	os_obtainmutex(libMutex);
3555 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3556 
3557 	for (i = 0; i < number_of_plugins; i++) {
3558 		if (plugintable[i].ownerId == portOid.ownerId) {
3559 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3560 			if (plugintable[i].hPlugin != NULL) {
3561 				os_obtainmutex(plugintable[i].pluginMutex);
3562 #ifdef WIN32
3563 				PassFunc =
3564 				    (IMA_GetNetworkPortStatusFn)
3565 				    GetProcAddress(plugintable[i].hPlugin,
3566 				    "IMA_GetNetworkPortStatus");
3567 #else
3568 				PassFunc =
3569 				    (IMA_GetNetworkPortStatusFn)
3570 				    dlsym(plugintable[i].hPlugin,
3571 				    "IMA_GetNetworkPortStatus");
3572 #endif
3573 
3574 				if (PassFunc != NULL) {
3575 					status = PassFunc(portOid, pStatus);
3576 				}
3577 				os_releasemutex(plugintable[i].pluginMutex);
3578 			}
3579 
3580 			break;
3581 		}
3582 	}
3583 	os_releasemutex(libMutex);
3584 	return (status);
3585 }
3586 
3587 
3588 IMA_API IMA_STATUS IMA_GetTargetOidList(
3589     IMA_OID Oid,
3590     IMA_OID_LIST **ppList) {
3591 	IMA_GetTargetOidListFn PassFunc;
3592 	IMA_FreeMemoryFn FreeFunc;
3593 	IMA_UINT i;
3594 	IMA_STATUS status;
3595 
3596 	if (number_of_plugins == -1)
3597 		InitLibrary();
3598 
3599 	if (ppList == NULL)
3600 		return (IMA_ERROR_INVALID_PARAMETER);
3601 
3602 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
3603 	    Oid.objectType != IMA_OBJECT_TYPE_LNP)
3604 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3605 
3606 	os_obtainmutex(libMutex);
3607 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3608 
3609 	for (i = 0; i < number_of_plugins; i++) {
3610 		if (plugintable[i].ownerId == Oid.ownerId) {
3611 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3612 			if (plugintable[i].hPlugin != NULL) {
3613 				os_obtainmutex(plugintable[i].pluginMutex);
3614 #ifdef WIN32
3615 				PassFunc =
3616 				    (IMA_GetTargetOidListFn)
3617 				    GetProcAddress(plugintable[i].hPlugin,
3618 				    "IMA_GetTargetOidList");
3619 #else
3620 				PassFunc =
3621 				    (IMA_GetTargetOidListFn)
3622 				    dlsym(plugintable[i].hPlugin,
3623 				    "IMA_GetTargetOidList");
3624 #endif
3625 
3626 				if (PassFunc != NULL) {
3627 					IMA_OID_LIST *ppOidList;
3628 					IMA_UINT listSize;
3629 					listSize = sizeof (IMA_OID_LIST);
3630 					status = PassFunc(Oid, &ppOidList);
3631 					if (IMA_SUCCESS(status)) {
3632 						*ppList =
3633 						    (IMA_OID_LIST*)calloc(1,
3634 						    sizeof (IMA_OID_LIST) +
3635 						    ((ppOidList->oidCount - 1)*
3636 						    sizeof (IMA_OID)));
3637 
3638 						if ((*ppList) == NULL) {
3639 							return (EUOS_ERROR);
3640 						}
3641 						else
3642 							memcpy((*ppList),
3643 							    ppOidList, listSize
3644 							    + (ppOidList->
3645 							    oidCount - 1)*
3646 							    sizeof (IMA_OID));
3647 #ifdef WIN32
3648 						FreeFunc = (IMA_FreeMemoryFn)
3649 						    GetProcAddress(
3650 						    plugintable[i].hPlugin,
3651 						    "IMA_FreeMemory");
3652 #else
3653 						FreeFunc = (IMA_FreeMemoryFn)
3654 						    dlsym(
3655 						    plugintable[i].hPlugin,
3656 						    "IMA_FreeMemory");
3657 #endif
3658 						if (FreeFunc != NULL) {
3659 							FreeFunc(ppOidList);
3660 						}
3661 					}
3662 				}
3663 				os_releasemutex(plugintable[i].pluginMutex);
3664 			}
3665 
3666 			break;
3667 		}
3668 	}
3669 	os_releasemutex(libMutex);
3670 	return (status);
3671 }
3672 
3673 
3674 IMA_API IMA_STATUS IMA_RemoveStaleData(
3675     IMA_OID lhbaId) {
3676 	IMA_RemoveStaleDataFn PassFunc;
3677 	IMA_UINT i;
3678 	IMA_STATUS status;
3679 
3680 	if (number_of_plugins == -1)
3681 		InitLibrary();
3682 
3683 	if (lhbaId.objectType != IMA_OBJECT_TYPE_LHBA)
3684 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3685 
3686 	os_obtainmutex(libMutex);
3687 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3688 
3689 	for (i = 0; i < number_of_plugins; i++) {
3690 		if (plugintable[i].ownerId == lhbaId.ownerId) {
3691 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3692 			if (plugintable[i].hPlugin != NULL) {
3693 				os_obtainmutex(plugintable[i].pluginMutex);
3694 #ifdef WIN32
3695 				PassFunc = (IMA_RemoveStaleDataFn)
3696 				    GetProcAddress(plugintable[i].hPlugin,
3697 				    "IMA_RemoveStaleData");
3698 #else
3699 				PassFunc = (IMA_RemoveStaleDataFn)
3700 				    dlsym(plugintable[i].hPlugin,
3701 				    "IMA_RemoveStaleData");
3702 #endif
3703 
3704 				if (PassFunc != NULL) {
3705 					status = PassFunc(lhbaId);
3706 				}
3707 				os_releasemutex(plugintable[i].pluginMutex);
3708 			}
3709 
3710 			break;
3711 		}
3712 	}
3713 	os_releasemutex(libMutex);
3714 	return (status);
3715 }
3716 
3717 
3718 IMA_API IMA_STATUS IMA_SetIsnsDiscovery(
3719     IMA_OID phbaId,
3720     IMA_BOOL enableIsnsDiscovery,
3721     IMA_ISNS_DISCOVERY_METHOD discoveryMethod,
3722     const IMA_HOST_ID *iSnsHost) {
3723 	IMA_SetIsnsDiscoveryFn PassFunc;
3724 	IMA_UINT i;
3725 	IMA_STATUS status;
3726 
3727 	if (number_of_plugins == -1)
3728 		InitLibrary();
3729 
3730 	if (enableIsnsDiscovery != IMA_TRUE &&
3731 	    enableIsnsDiscovery != IMA_FALSE)
3732 		return (IMA_ERROR_INVALID_PARAMETER);
3733 
3734 	if (enableIsnsDiscovery == IMA_TRUE && iSnsHost == NULL)
3735 		return (IMA_ERROR_INVALID_PARAMETER);
3736 
3737 	if (discoveryMethod != IMA_ISNS_DISCOVERY_METHOD_STATIC &&
3738 	    discoveryMethod != IMA_ISNS_DISCOVERY_METHOD_DHCP &&
3739 	    discoveryMethod != IMA_ISNS_DISCOVERY_METHOD_SLP)
3740 		return (IMA_ERROR_INVALID_PARAMETER);
3741 
3742 	if (phbaId.objectType != IMA_OBJECT_TYPE_PHBA &&
3743 	    phbaId.objectType != IMA_OBJECT_TYPE_LHBA) {
3744 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3745 	}
3746 
3747 	os_obtainmutex(libMutex);
3748 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3749 
3750 	for (i = 0; i < number_of_plugins; i++) {
3751 		if (plugintable[i].ownerId == phbaId.ownerId) {
3752 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3753 			if (plugintable[i].hPlugin != NULL) {
3754 				os_obtainmutex(plugintable[i].pluginMutex);
3755 #ifdef WIN32
3756 				PassFunc =
3757 				    (IMA_SetIsnsDiscoveryFn)
3758 				    GetProcAddress(plugintable[i].hPlugin,
3759 				    "IMA_SetIsnsDiscovery");
3760 #else
3761 				PassFunc =
3762 				    (IMA_SetIsnsDiscoveryFn)
3763 				    dlsym(plugintable[i].hPlugin,
3764 				    "IMA_SetIsnsDiscovery");
3765 #endif
3766 
3767 				if (PassFunc != NULL) {
3768 					status = PassFunc(phbaId,
3769 					    enableIsnsDiscovery,
3770 					    discoveryMethod, iSnsHost);
3771 				}
3772 				os_releasemutex(plugintable[i].pluginMutex);
3773 			}
3774 
3775 			break;
3776 		}
3777 	}
3778 	os_releasemutex(libMutex);
3779 	return (status);
3780 }
3781 
3782 
3783 IMA_API IMA_STATUS IMA_SetSlpDiscovery(
3784     IMA_OID phbaId,
3785     IMA_BOOL enableSlpDiscovery) {
3786 	IMA_SetSlpDiscoveryFn PassFunc;
3787 	IMA_UINT i;
3788 	IMA_STATUS status;
3789 
3790 	if (number_of_plugins == -1)
3791 		InitLibrary();
3792 
3793 	if (enableSlpDiscovery != IMA_TRUE &&
3794 	    enableSlpDiscovery != IMA_FALSE)
3795 		return (IMA_ERROR_INVALID_PARAMETER);
3796 
3797 	if (phbaId.objectType != IMA_OBJECT_TYPE_PHBA &&
3798 	    phbaId.objectType != IMA_OBJECT_TYPE_LHBA)
3799 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3800 
3801 	os_obtainmutex(libMutex);
3802 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3803 
3804 	for (i = 0; i < number_of_plugins; i++) {
3805 		if (plugintable[i].ownerId == phbaId.ownerId) {
3806 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3807 			if (plugintable[i].hPlugin != NULL) {
3808 				os_obtainmutex(plugintable[i].pluginMutex);
3809 #ifdef WIN32
3810 				PassFunc =
3811 				    (IMA_SetSlpDiscoveryFn)
3812 				    GetProcAddress(plugintable[i].hPlugin,
3813 				    "IMA_SetSlpDiscovery");
3814 #else
3815 				PassFunc = (IMA_SetSlpDiscoveryFn)
3816 				    dlsym(plugintable[i].hPlugin,
3817 				    "IMA_SetSlpDiscovery");
3818 #endif
3819 
3820 				if (PassFunc != NULL) {
3821 					status = PassFunc(
3822 					    phbaId,
3823 					    enableSlpDiscovery);
3824 				}
3825 				os_releasemutex(plugintable[i].pluginMutex);
3826 			}
3827 
3828 			break;
3829 		}
3830 	}
3831 	os_releasemutex(libMutex);
3832 	return (status);
3833 }
3834 
3835 
3836 IMA_API IMA_STATUS IMA_SetStaticDiscovery(
3837     IMA_OID phbaId,
3838     IMA_BOOL enableStaticDiscovery) {
3839 	IMA_SetStaticDiscoveryFn PassFunc;
3840 	IMA_UINT i;
3841 	IMA_STATUS status;
3842 
3843 	if (number_of_plugins == -1)
3844 		InitLibrary();
3845 
3846 	if (enableStaticDiscovery != IMA_TRUE &&
3847 	    enableStaticDiscovery != IMA_FALSE)
3848 		return (IMA_ERROR_INVALID_PARAMETER);
3849 
3850 	if (phbaId.objectType != IMA_OBJECT_TYPE_PHBA &&
3851 	    phbaId.objectType != IMA_OBJECT_TYPE_LHBA)
3852 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3853 
3854 	os_obtainmutex(libMutex);
3855 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3856 
3857 	for (i = 0; i < number_of_plugins; i++) {
3858 		if (plugintable[i].ownerId == phbaId.ownerId) {
3859 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3860 			if (plugintable[i].hPlugin != NULL) {
3861 				os_obtainmutex(plugintable[i].pluginMutex);
3862 #ifdef WIN32
3863 				PassFunc = (IMA_SetStaticDiscoveryFn)
3864 				    GetProcAddress(plugintable[i].hPlugin,
3865 				    "IMA_SetStaticDiscovery");
3866 #else
3867 				PassFunc = (IMA_SetStaticDiscoveryFn)
3868 				    dlsym(plugintable[i].hPlugin,
3869 				    "IMA_SetStaticDiscovery");
3870 #endif
3871 
3872 				if (PassFunc != NULL) {
3873 					status = PassFunc(
3874 					    phbaId,
3875 					    enableStaticDiscovery);
3876 				}
3877 				os_releasemutex(plugintable[i].pluginMutex);
3878 			}
3879 
3880 			break;
3881 		}
3882 	}
3883 	os_releasemutex(libMutex);
3884 	return (status);
3885 }
3886 
3887 
3888 IMA_API IMA_STATUS IMA_SetSendTargetsDiscovery(
3889     IMA_OID phbaId,
3890     IMA_BOOL enableSendTargetsDiscovery) {
3891 	IMA_SetSendTargetsDiscoveryFn PassFunc;
3892 	IMA_UINT i;
3893 	IMA_STATUS status;
3894 
3895 	if (number_of_plugins == -1)
3896 		InitLibrary();
3897 
3898 	if (enableSendTargetsDiscovery != IMA_TRUE &&
3899 	    enableSendTargetsDiscovery != IMA_FALSE)
3900 		return (IMA_ERROR_INVALID_PARAMETER);
3901 
3902 	if (phbaId.objectType != IMA_OBJECT_TYPE_PHBA &&
3903 	    phbaId.objectType != IMA_OBJECT_TYPE_LHBA) {
3904 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
3905 	}
3906 
3907 	os_obtainmutex(libMutex);
3908 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3909 
3910 	for (i = 0; i < number_of_plugins; i++) {
3911 		if (plugintable[i].ownerId == phbaId.ownerId) {
3912 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3913 			if (plugintable[i].hPlugin != NULL) {
3914 				os_obtainmutex(plugintable[i].pluginMutex);
3915 #ifdef WIN32
3916 				PassFunc = (IMA_SetSendTargetsDiscoveryFn)
3917 				    GetProcAddress(plugintable[i].hPlugin,
3918 				    "IMA_SetSendTargetsDiscovery");
3919 #else
3920 				PassFunc = (IMA_SetSendTargetsDiscoveryFn)
3921 				    dlsym(plugintable[i].hPlugin,
3922 				    "IMA_SetSendTargetsDiscovery");
3923 #endif
3924 
3925 				if (PassFunc != NULL) {
3926 					status = PassFunc(
3927 					    phbaId,
3928 					    enableSendTargetsDiscovery);
3929 				}
3930 				os_releasemutex(
3931 				    plugintable[i].pluginMutex);
3932 			}
3933 
3934 			break;
3935 		}
3936 	}
3937 	os_releasemutex(libMutex);
3938 	return (status);
3939 }
3940 
3941 /*
3942  * this forces plugins to rescan all iscsi targets on this
3943  * ipaddress/port and return a
3944  * list of discovered targets.
3945  * ERROR/todo:
3946  * according to IMA spec., pTargetOidList is allocated by
3947  * the caller for library to return data,
3948  * how does a caller know how much space it will be?
3949  * pTargetOidList should be allocated by the library/plugin
3950  * like IMA_GetLnpOidList
3951  */
3952 IMA_API IMA_STATUS IMA_AddPhbaStaticDiscoveryTarget(
3953     IMA_OID phbaOid,
3954     const IMA_TARGET_ADDRESS targetAddress,
3955     IMA_OID_LIST **pTargetOidList) {
3956 	IMA_AddPhbaStaticDiscoveryTargetFn PassFunc;
3957 	IMA_FreeMemoryFn FreeFunc;
3958 	IMA_UINT i;
3959 	IMA_STATUS status;
3960 
3961 	if (number_of_plugins == -1)
3962 		InitLibrary();
3963 
3964 	os_obtainmutex(libMutex);
3965 	status = IMA_ERROR_OBJECT_NOT_FOUND;
3966 
3967 	for (i = 0; i < number_of_plugins; i++) {
3968 
3969 		if (plugintable[i].ownerId == phbaOid.ownerId) {
3970 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
3971 			if (plugintable[i].hPlugin != NULL) {
3972 				os_obtainmutex(plugintable[i].pluginMutex);
3973 #ifdef WIN32
3974 				PassFunc =
3975 				    (IMA_AddPhbaStaticDiscoveryTargetFn)
3976 				    GetProcAddress(plugintable[i].hPlugin,
3977 				    "IMA_AddPhbaStaticDiscoveryTarget");
3978 #else
3979 				PassFunc =
3980 				    (IMA_AddPhbaStaticDiscoveryTargetFn)
3981 				    dlsym(plugintable[i].hPlugin,
3982 				    "IMA_AddPhbaStaticDiscoveryTarget");
3983 #endif
3984 
3985 				if (PassFunc != NULL) {
3986 					IMA_OID_LIST *ppOidList;
3987 					IMA_UINT listSize;
3988 					listSize =
3989 					    sizeof (IMA_OID_LIST);
3990 					status = PassFunc(phbaOid,
3991 					    targetAddress, &ppOidList);
3992 					if (IMA_SUCCESS(status)) {
3993 
3994 						(*pTargetOidList) =
3995 						    (IMA_OID_LIST*)
3996 						    calloc(1, listSize +
3997 						    (ppOidList->oidCount-1)*
3998 						    sizeof (IMA_OID));
3999 
4000 						if ((*pTargetOidList) == NULL) {
4001 							status =
4002 							    EUOS_ERROR;
4003 						}
4004 						memcpy((*pTargetOidList),
4005 						    ppOidList,
4006 						    listSize +
4007 						    (ppOidList->oidCount-1)*
4008 						    sizeof (IMA_OID));
4009 #ifdef WIN32
4010 						FreeFunc = (IMA_FreeMemoryFn)
4011 						    GetProcAddress(
4012 						    plugintable[i].hPlugin,
4013 						    "IMA_FreeMemory");
4014 #else
4015 						FreeFunc = (IMA_FreeMemoryFn)
4016 						    dlsym(
4017 						    plugintable[i].hPlugin,
4018 						    "IMA_FreeMemory");
4019 #endif
4020 						if (FreeFunc != NULL) {
4021 							FreeFunc(ppOidList);
4022 						}
4023 					}
4024 				}
4025 				os_releasemutex(plugintable[i].pluginMutex);
4026 			}
4027 
4028 			break;
4029 		}
4030 	}
4031 	os_releasemutex(libMutex);
4032 	return (status);
4033 }
4034 
4035 
4036 IMA_API IMA_STATUS IMA_RemovePhbaStaticDiscoveryTarget(
4037     IMA_OID phbaOid,
4038     IMA_OID targetOid) {
4039 	IMA_RemovePhbaStaticDiscoveryTargetFn PassFunc;
4040 	IMA_UINT i;
4041 	IMA_STATUS status;
4042 
4043 	if (number_of_plugins == -1)
4044 		InitLibrary();
4045 
4046 	os_obtainmutex(libMutex);
4047 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4048 
4049 	for (i = 0; i < number_of_plugins; i++) {
4050 		if (plugintable[i].ownerId == targetOid.ownerId) {
4051 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4052 			if (plugintable[i].hPlugin != NULL) {
4053 				os_obtainmutex(plugintable[i].pluginMutex);
4054 #ifdef WIN32
4055 				PassFunc =
4056 				    (IMA_RemovePhbaStaticDiscoveryTargetFn)
4057 				    GetProcAddress(plugintable[i].hPlugin,
4058 				    "IMA_RemovePhbaStaticDiscoveryTarget");
4059 #else
4060 				PassFunc =
4061 				    (IMA_RemovePhbaStaticDiscoveryTargetFn)
4062 				    dlsym(plugintable[i].hPlugin,
4063 				    "IMA_RemovePhbaStaticDiscoveryTarget");
4064 #endif
4065 
4066 				if (PassFunc != NULL) {
4067 					status = PassFunc(phbaOid, targetOid);
4068 				}
4069 				os_releasemutex(plugintable[i].pluginMutex);
4070 			}
4071 
4072 			break;
4073 		}
4074 	}
4075 	os_releasemutex(libMutex);
4076 	return (status);
4077 }
4078 
4079 
4080 IMA_API IMA_STATUS IMA_GetPnpOidList(
4081     IMA_OID Oid,
4082     IMA_OID_LIST **ppList) {
4083 	IMA_GetPnpOidListFn PassFunc;
4084 	IMA_FreeMemoryFn FreeFunc;
4085 	IMA_UINT i;
4086 	IMA_STATUS status;
4087 
4088 	if (number_of_plugins == -1)
4089 		InitLibrary();
4090 
4091 	if (ppList == NULL)
4092 		return (IMA_ERROR_INVALID_PARAMETER);
4093 
4094 	if (Oid.objectType != IMA_OBJECT_TYPE_PHBA &&
4095 	    Oid.objectType != IMA_OBJECT_TYPE_LNP)
4096 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4097 
4098 	os_obtainmutex(libMutex);
4099 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4100 	for (i = 0; i < number_of_plugins; i++) {
4101 
4102 		if (plugintable[i].ownerId == Oid.ownerId) {
4103 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4104 			if (plugintable[i].hPlugin != NULL) {
4105 				os_obtainmutex(plugintable[i].pluginMutex);
4106 #ifdef WIN32
4107 				PassFunc = (IMA_GetPnpOidListFn)
4108 				    GetProcAddress(plugintable[i].hPlugin,
4109 				    "IMA_GetPnpOidList");
4110 #else
4111 				PassFunc = (IMA_GetPnpOidListFn)
4112 				    dlsym(plugintable[i].hPlugin,
4113 				    "IMA_GetPnpOidList");
4114 #endif
4115 
4116 				if (PassFunc != NULL) {
4117 					IMA_OID_LIST *ppOidList;
4118 
4119 					status = PassFunc(Oid, &ppOidList);
4120 					if (IMA_SUCCESS(status)) {
4121 						IMA_UINT listSize;
4122 						listSize =
4123 						    sizeof (IMA_OID_LIST);
4124 						*ppList = (IMA_OID_LIST*)
4125 						    calloc(1, listSize +
4126 						    (ppOidList->oidCount-1)*
4127 						    sizeof (IMA_OID));
4128 
4129 						if ((*ppList) == NULL) {
4130 							status =
4131 							    EUOS_ERROR;
4132 						}
4133 						else
4134 							memcpy((*ppList),
4135 							    ppOidList,
4136 							    listSize +
4137 							    (ppOidList->
4138 							    oidCount - 1)*
4139 							    sizeof (IMA_OID));
4140 #ifdef WIN32
4141 						FreeFunc = (IMA_FreeMemoryFn)
4142 						    GetProcAddress(
4143 						    plugintable[i].hPlugin,
4144 						    "IMA_FreeMemory");
4145 #else
4146 						FreeFunc = (IMA_FreeMemoryFn)
4147 						    dlsym(
4148 						    plugintable[i].hPlugin,
4149 						    "IMA_FreeMemory");
4150 #endif
4151 						if (FreeFunc != NULL) {
4152 							FreeFunc(ppOidList);
4153 						}
4154 					}
4155 				}
4156 				os_releasemutex(plugintable[i].pluginMutex);
4157 			}
4158 
4159 			break;
4160 		}
4161 	}
4162 	os_releasemutex(libMutex);
4163 	return (status);
4164 }
4165 
4166 
4167 IMA_API IMA_STATUS IMA_GetPhbaDownloadProperties(
4168     IMA_OID phbaId,
4169     IMA_PHBA_DOWNLOAD_PROPERTIES *pProps) {
4170 	IMA_GetPhbaDownloadPropertiesFn PassFunc;
4171 	IMA_UINT i;
4172 	IMA_STATUS status;
4173 
4174 	if (number_of_plugins == -1)
4175 		InitLibrary();
4176 
4177 	if (pProps == NULL)
4178 		return (IMA_ERROR_INVALID_PARAMETER);
4179 
4180 	if (phbaId.objectType != IMA_OBJECT_TYPE_PHBA)
4181 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4182 
4183 	os_obtainmutex(libMutex);
4184 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4185 
4186 	for (i = 0; i < number_of_plugins; i++) {
4187 		if (plugintable[i].ownerId == phbaId.ownerId) {
4188 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4189 			if (plugintable[i].hPlugin != NULL) {
4190 				os_obtainmutex(plugintable[i].pluginMutex);
4191 #ifdef WIN32
4192 				PassFunc =
4193 				    (IMA_GetPhbaDownloadPropertiesFn)
4194 				    GetProcAddress(plugintable[i].hPlugin,
4195 				    "IMA_GetPhbaDownloadProperties");
4196 #else
4197 				PassFunc = (IMA_GetPhbaDownloadPropertiesFn)
4198 				    dlsym(plugintable[i].hPlugin,
4199 				    "IMA_GetPhbaDownloadProperties");
4200 #endif
4201 
4202 				if (PassFunc != NULL) {
4203 					status = PassFunc(phbaId, pProps);
4204 				}
4205 				os_releasemutex(plugintable[i].pluginMutex);
4206 			}
4207 
4208 			break;
4209 		}
4210 	}
4211 	os_releasemutex(libMutex);
4212 	return (status);
4213 }
4214 
4215 
4216 IMA_API IMA_STATUS IMA_IsPhbaDownloadFile(
4217     IMA_OID phbaId,
4218     const IMA_WCHAR *pFileName,
4219     IMA_PHBA_DOWNLOAD_IMAGE_PROPERTIES *pProps) {
4220 	IMA_IsPhbaDownloadFileFn PassFunc;
4221 	IMA_UINT i;
4222 	IMA_STATUS status;
4223 
4224 	if (number_of_plugins == -1)
4225 		InitLibrary();
4226 
4227 	if (pFileName == NULL || pProps == NULL)
4228 		return (IMA_ERROR_INVALID_PARAMETER);
4229 
4230 	if (phbaId.objectType != IMA_OBJECT_TYPE_PHBA)
4231 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4232 
4233 	os_obtainmutex(libMutex);
4234 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4235 
4236 	for (i = 0; i < number_of_plugins; i++) {
4237 		if (plugintable[i].ownerId == phbaId.ownerId) {
4238 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4239 			if (plugintable[i].hPlugin != NULL) {
4240 				os_obtainmutex(plugintable[i].pluginMutex);
4241 #ifdef WIN32
4242 				PassFunc = (IMA_IsPhbaDownloadFileFn)
4243 				    GetProcAddress(plugintable[i].hPlugin,
4244 				    "IMA_IsPhbaDownloadFile");
4245 #else
4246 				PassFunc = (IMA_IsPhbaDownloadFileFn)
4247 				    dlsym(plugintable[i].hPlugin,
4248 				    "IMA_IsPhbaDownloadFile");
4249 #endif
4250 
4251 				if (PassFunc != NULL) {
4252 					status = PassFunc(
4253 					    phbaId, pFileName, pProps);
4254 				}
4255 				os_releasemutex(plugintable[i].pluginMutex);
4256 			}
4257 
4258 			break;
4259 		}
4260 	}
4261 	os_releasemutex(libMutex);
4262 	return (status);
4263 }
4264 
4265 
4266 IMA_API IMA_STATUS IMA_PhbaDownload(
4267     IMA_OID phbaId,
4268     IMA_PHBA_DOWNLOAD_IMAGE_TYPE imageType,
4269     const IMA_WCHAR *pFileName) {
4270 	IMA_PhbaDownloadFn PassFunc;
4271 	IMA_UINT i;
4272 	IMA_STATUS status;
4273 
4274 	if (number_of_plugins == -1)
4275 		InitLibrary();
4276 
4277 	if (phbaId.objectType != IMA_OBJECT_TYPE_PHBA)
4278 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4279 
4280 	if (imageType != IMA_DOWNLOAD_IMAGE_TYPE_FIRMWARE &&
4281 	    imageType != IMA_DOWNLOAD_IMAGE_TYPE_OPTION_ROM &&
4282 	    imageType != IMA_DOWNLOAD_IMAGE_TYPE_ALL &&
4283 	    imageType != IMA_DOWNLOAD_IMAGE_TYPE_BOOTCODE)
4284 	    return (IMA_ERROR_INVALID_PARAMETER);
4285 
4286 	if (pFileName == NULL)
4287 		return (IMA_ERROR_INVALID_PARAMETER);
4288 
4289 	os_obtainmutex(libMutex);
4290 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4291 
4292 	for (i = 0; i < number_of_plugins; i++) {
4293 		if (plugintable[i].ownerId == phbaId.ownerId) {
4294 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4295 			if (plugintable[i].hPlugin != NULL) {
4296 				os_obtainmutex(plugintable[i].pluginMutex);
4297 #ifdef WIN32
4298 				PassFunc = (IMA_PhbaDownloadFn)
4299 				    GetProcAddress(plugintable[i].hPlugin,
4300 				    "IMA_PhbaDownload");
4301 #else
4302 				PassFunc = (IMA_PhbaDownloadFn)
4303 				    dlsym(plugintable[i].hPlugin,
4304 				    "IMA_PhbaDownload");
4305 #endif
4306 
4307 				if (PassFunc != NULL) {
4308 					status = PassFunc(
4309 					    phbaId, imageType, pFileName);
4310 				}
4311 				os_releasemutex(plugintable[i].pluginMutex);
4312 			}
4313 
4314 			break;
4315 		}
4316 	}
4317 	os_releasemutex(libMutex);
4318 	return (status);
4319 }
4320 
4321 
4322 IMA_API IMA_STATUS IMA_GetNetworkPortalProperties(
4323     IMA_OID networkPortalId,
4324     IMA_NETWORK_PORTAL_PROPERTIES *pProps) {
4325 	IMA_GetNetworkPortalPropertiesFn PassFunc;
4326 	IMA_UINT i;
4327 	IMA_STATUS status;
4328 
4329 	if (number_of_plugins == -1)
4330 		InitLibrary();
4331 
4332 	if (pProps == NULL)
4333 		return (IMA_ERROR_INVALID_PARAMETER);
4334 
4335 	if (networkPortalId.objectType != IMA_OBJECT_TYPE_NETWORK_PORTAL)
4336 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4337 
4338 	os_obtainmutex(libMutex);
4339 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4340 
4341 	for (i = 0; i < number_of_plugins; i++) {
4342 		if (plugintable[i].ownerId == networkPortalId.ownerId) {
4343 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4344 			if (plugintable[i].hPlugin != NULL) {
4345 				os_obtainmutex(plugintable[i].pluginMutex);
4346 #ifdef WIN32
4347 				PassFunc =
4348 				    (IMA_GetNetworkPortalPropertiesFn)
4349 				    GetProcAddress(plugintable[i].hPlugin,
4350 				    "IMA_GetNetworkPortalProperties");
4351 #else
4352 				PassFunc =
4353 				    (IMA_GetNetworkPortalPropertiesFn)
4354 				    dlsym(plugintable[i].hPlugin,
4355 				    "IMA_GetNetworkPortalProperties");
4356 #endif
4357 
4358 				if (PassFunc != NULL) {
4359 					status = PassFunc(
4360 					    networkPortalId, pProps);
4361 				}
4362 				os_releasemutex(plugintable[i].pluginMutex);
4363 			}
4364 
4365 			break;
4366 		}
4367 	}
4368 	os_releasemutex(libMutex);
4369 	return (status);
4370 }
4371 
4372 
4373 IMA_API IMA_STATUS IMA_SetNetworkPortalIpAddress(
4374     IMA_OID networkPortalId,
4375     const IMA_IP_ADDRESS NewIpAddress) {
4376 	IMA_SetNetworkPortalIpAddressFn PassFunc;
4377 	IMA_UINT i;
4378 	IMA_STATUS status;
4379 
4380 	if (number_of_plugins == -1)
4381 		InitLibrary();
4382 
4383 	if (networkPortalId.objectType != IMA_OBJECT_TYPE_NETWORK_PORTAL)
4384 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4385 
4386 	os_obtainmutex(libMutex);
4387 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4388 
4389 	for (i = 0; i < number_of_plugins; i++) {
4390 		if (plugintable[i].ownerId == networkPortalId.ownerId) {
4391 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4392 			if (plugintable[i].hPlugin != NULL) {
4393 				os_obtainmutex(plugintable[i].pluginMutex);
4394 #ifdef WIN32
4395 				PassFunc =
4396 				    (IMA_SetNetworkPortalIpAddressFn)
4397 				    GetProcAddress(plugintable[i].hPlugin,
4398 				    "IMA_SetNetworkPortalIpAddress");
4399 #else
4400 				PassFunc = (IMA_SetNetworkPortalIpAddressFn)
4401 				    dlsym(plugintable[i].hPlugin,
4402 				    "IMA_SetNetworkPortalIpAddress");
4403 #endif
4404 
4405 				if (PassFunc != NULL) {
4406 					status = PassFunc(
4407 					    networkPortalId, NewIpAddress);
4408 				}
4409 				os_releasemutex(plugintable[i].pluginMutex);
4410 			}
4411 
4412 			break;
4413 		}
4414 	}
4415 	os_releasemutex(libMutex);
4416 	return (status);
4417 }
4418 
4419 
4420 IMA_API IMA_STATUS IMA_GetLnpOidList(
4421     IMA_OID_LIST **ppList) {
4422 	IMA_GetLnpOidListFn PassFunc;
4423 	IMA_FreeMemoryFn    FreeFunc;
4424 
4425 	IMA_UINT i;
4426 	IMA_UINT j;
4427 	IMA_UINT totalIdCount;
4428 	IMA_STATUS status;
4429 
4430 	if (number_of_plugins == -1)
4431 		InitLibrary();
4432 
4433 	if (ppList == NULL)
4434 		return (IMA_ERROR_INVALID_PARAMETER);
4435 
4436 	os_obtainmutex(libMutex);
4437 	// Get total id count first
4438 	totalIdCount = 0;
4439 
4440 	for (i = 0; i < number_of_plugins; i++) {
4441 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4442 		if (plugintable[i].hPlugin != NULL) {
4443 			os_obtainmutex(plugintable[i].pluginMutex);
4444 #ifdef WIN32
4445 			PassFunc = (IMA_GetLnpOidListFn)
4446 			    GetProcAddress(plugintable[i].hPlugin,
4447 			    "IMA_GetLnpOidList");
4448 #else
4449 			PassFunc = (IMA_GetLnpOidListFn)
4450 			    dlsym(plugintable[i].hPlugin,
4451 			    "IMA_GetLnpOidList");
4452 #endif
4453 			if (PassFunc != NULL) {
4454 				IMA_OID_LIST *ppOidList;
4455 				status = PassFunc(&ppOidList);
4456 				if (status == IMA_STATUS_SUCCESS) {
4457 					totalIdCount += ppOidList->oidCount;
4458 #ifdef WIN32
4459 					FreeFunc = (IMA_FreeMemoryFn)
4460 					    GetProcAddress(
4461 					    plugintable[i].hPlugin,
4462 					    "IMA_FreeMemory");
4463 #else
4464 					FreeFunc = (IMA_FreeMemoryFn)
4465 					    dlsym(plugintable[i].hPlugin,
4466 					    "IMA_FreeMemory");
4467 #endif
4468 					if (FreeFunc != NULL) {
4469 						FreeFunc(ppOidList);
4470 					}
4471 				}
4472 			}
4473 			os_releasemutex(plugintable[i].pluginMutex);
4474 		}
4475 		if (status != IMA_STATUS_SUCCESS) {
4476 			break;
4477 		}
4478 
4479 	}
4480 
4481 
4482 	*ppList = (IMA_OID_LIST*)calloc(1,
4483 	    sizeof (IMA_OID_LIST) + (totalIdCount - 1)* sizeof (IMA_OID));
4484 
4485 	if ((*ppList) == NULL) {
4486 		os_releasemutex(libMutex);
4487 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
4488 	}
4489 
4490 	(*ppList)->oidCount = totalIdCount;
4491 
4492 	// 2nd pass to copy the id lists
4493 	totalIdCount = 0;
4494 	status = IMA_STATUS_SUCCESS;
4495 	for (i = 0; i < number_of_plugins; i++) {
4496 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4497 		if (plugintable[i].hPlugin != NULL) {
4498 			os_obtainmutex(plugintable[i].pluginMutex);
4499 #ifdef WIN32
4500 			PassFunc = (IMA_GetLnpOidListFn)
4501 			    GetProcAddress(plugintable[i].hPlugin,
4502 			    "IMA_GetLnpOidList");
4503 #else
4504 			PassFunc = (IMA_GetLnpOidListFn)
4505 			    dlsym(plugintable[i].hPlugin,
4506 			    "IMA_GetLnpOidList");
4507 #endif
4508 			if (PassFunc != NULL) {
4509 				IMA_OID_LIST *ppOidList;
4510 				status = PassFunc(&ppOidList);
4511 				if (status == IMA_STATUS_SUCCESS) {
4512 					for (j = 0; (j < ppOidList->oidCount) &&
4513 					    (totalIdCount <
4514 					    (*ppList)->oidCount);
4515 					    j++) {
4516 						(*ppList)->oids[totalIdCount].
4517 						    objectType =
4518 						    ppOidList->oids[j].
4519 						    objectType;
4520 						(*ppList)->oids[totalIdCount].
4521 						    objectSequenceNumber =
4522 						    ppOidList->oids[j].
4523 						    objectSequenceNumber;
4524 
4525 						(*ppList)->oids[totalIdCount].
4526 						    ownerId =
4527 						    ppOidList->oids[j].ownerId;
4528 						totalIdCount++;
4529 					}
4530 #ifdef WIN32
4531 					FreeFunc = (IMA_FreeMemoryFn)
4532 					    GetProcAddress(
4533 					    plugintable[i].hPlugin,
4534 					    "IMA_FreeMemory");
4535 #else
4536 					FreeFunc = (IMA_FreeMemoryFn)
4537 					    dlsym(plugintable[i].hPlugin,
4538 					    "IMA_FreeMemory");
4539 #endif
4540 					if (FreeFunc != NULL) {
4541 						FreeFunc(ppOidList);
4542 					}
4543 				}
4544 			}
4545 			os_releasemutex(plugintable[i].pluginMutex);
4546 		}
4547 		if (status != IMA_STATUS_SUCCESS) {
4548 			free(*ppList);
4549 			break;
4550 		}
4551 
4552 	}
4553 	os_releasemutex(libMutex);
4554 	return (status);
4555 }
4556 
4557 
4558 IMA_API IMA_STATUS IMA_GetLnpProperties(
4559     IMA_OID lnpId,
4560     IMA_LNP_PROPERTIES *pProps) {
4561 	IMA_GetLnpPropertiesFn PassFunc;
4562 	IMA_UINT i;
4563 	IMA_STATUS status;
4564 
4565 	if (number_of_plugins == -1)
4566 		InitLibrary();
4567 
4568 	if (pProps == NULL)
4569 		return (IMA_ERROR_INVALID_PARAMETER);
4570 
4571 	if (lnpId.objectType != IMA_OBJECT_TYPE_LNP)
4572 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4573 
4574 	os_obtainmutex(libMutex);
4575 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4576 
4577 	for (i = 0; i < number_of_plugins; i++) {
4578 		if (plugintable[i].ownerId == lnpId.ownerId) {
4579 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4580 			if (plugintable[i].hPlugin != NULL) {
4581 				os_obtainmutex(plugintable[i].pluginMutex);
4582 #ifdef WIN32
4583 				PassFunc = (IMA_GetLnpPropertiesFn)
4584 				    GetProcAddress(plugintable[i].hPlugin,
4585 				    "IMA_GetLnpProperties");
4586 #else
4587 				PassFunc = (IMA_GetLnpPropertiesFn)
4588 				    dlsym(plugintable[i].hPlugin,
4589 				    "IMA_GetLnpProperties");
4590 #endif
4591 
4592 				if (PassFunc != NULL) {
4593 					status = PassFunc(lnpId, pProps);
4594 				}
4595 				os_releasemutex(plugintable[i].pluginMutex);
4596 			}
4597 
4598 			break;
4599 		}
4600 	}
4601 	os_releasemutex(libMutex);
4602 	return (status);
4603 }
4604 
4605 
4606 IMA_API IMA_STATUS IMA_GetPnpProperties(
4607     IMA_OID pnpId,
4608     IMA_PNP_PROPERTIES *pProps) {
4609 	IMA_GetPnpPropertiesFn PassFunc;
4610 	IMA_UINT i;
4611 	IMA_STATUS status;
4612 
4613 	if (number_of_plugins == -1)
4614 		InitLibrary();
4615 
4616 	if (pProps == NULL)
4617 		return (IMA_ERROR_INVALID_PARAMETER);
4618 
4619 	if (pnpId.objectType != IMA_OBJECT_TYPE_PNP)
4620 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4621 
4622 	os_obtainmutex(libMutex);
4623 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4624 
4625 	for (i = 0; i < number_of_plugins; i++) {
4626 		if (plugintable[i].ownerId == pnpId.ownerId) {
4627 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4628 			if (plugintable[i].hPlugin != NULL) {
4629 				os_obtainmutex(plugintable[i].pluginMutex);
4630 #ifdef WIN32
4631 				PassFunc = (IMA_GetPnpPropertiesFn)
4632 				    GetProcAddress(plugintable[i].hPlugin,
4633 				    "IMA_GetPnpProperties");
4634 #else
4635 				PassFunc = (IMA_GetPnpPropertiesFn)
4636 				    dlsym(plugintable[i].hPlugin,
4637 				    "IMA_GetPnpProperties");
4638 #endif
4639 
4640 				if (PassFunc != NULL) {
4641 					status = PassFunc(pnpId, pProps);
4642 				}
4643 				os_releasemutex(plugintable[i].pluginMutex);
4644 			}
4645 
4646 			break;
4647 		}
4648 	}
4649 	os_releasemutex(libMutex);
4650 	return (status);
4651 }
4652 
4653 
4654 IMA_API IMA_STATUS IMA_GetPnpStatistics(
4655     IMA_OID pnpId,
4656     IMA_PNP_STATISTICS *pStats) {
4657 	IMA_GetPnpStatisticsFn PassFunc;
4658 	IMA_UINT i;
4659 	IMA_STATUS status;
4660 
4661 	if (number_of_plugins == -1)
4662 		InitLibrary();
4663 
4664 	if (pStats == NULL)
4665 		return (IMA_ERROR_INVALID_PARAMETER);
4666 
4667 	if (pnpId.objectType != IMA_OBJECT_TYPE_PNP)
4668 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4669 
4670 	os_obtainmutex(libMutex);
4671 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4672 
4673 	for (i = 0; i < number_of_plugins; i++) {
4674 		if (plugintable[i].ownerId == pnpId.ownerId) {
4675 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4676 			if (plugintable[i].hPlugin != NULL) {
4677 				os_obtainmutex(plugintable[i].pluginMutex);
4678 #ifdef WIN32
4679 				PassFunc = (IMA_GetPnpStatisticsFn)
4680 				    GetProcAddress(plugintable[i].hPlugin,
4681 				    "IMA_GetPnpStatistics");
4682 #else
4683 				PassFunc = (IMA_GetPnpStatisticsFn)
4684 				    dlsym(plugintable[i].hPlugin,
4685 				    "IMA_GetPnpStatistics");
4686 #endif
4687 
4688 				if (PassFunc != NULL) {
4689 					status = PassFunc(pnpId, pStats);
4690 				}
4691 				os_releasemutex(plugintable[i].pluginMutex);
4692 			}
4693 
4694 			break;
4695 		}
4696 	}
4697 	os_releasemutex(libMutex);
4698 	return (status);
4699 }
4700 
4701 
4702 IMA_API IMA_STATUS IMA_GetTargetProperties(
4703     IMA_OID targetId,
4704     IMA_TARGET_PROPERTIES *pProps) {
4705 	IMA_GetTargetPropertiesFn PassFunc;
4706 	IMA_UINT i;
4707 	IMA_STATUS status;
4708 
4709 	if (number_of_plugins == -1)
4710 		InitLibrary();
4711 
4712 	if (pProps == NULL)
4713 		return (IMA_ERROR_INVALID_PARAMETER);
4714 
4715 	if (targetId.objectType != IMA_OBJECT_TYPE_TARGET)
4716 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4717 
4718 	os_obtainmutex(libMutex);
4719 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4720 
4721 	for (i = 0; i < number_of_plugins; i++) {
4722 		if (plugintable[i].ownerId == targetId.ownerId) {
4723 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4724 			if (plugintable[i].hPlugin != NULL) {
4725 				os_obtainmutex(plugintable[i].pluginMutex);
4726 #ifdef WIN32
4727 				PassFunc = (IMA_GetTargetPropertiesFn)
4728 				    GetProcAddress(plugintable[i].hPlugin,
4729 				    "IMA_GetTargetProperties");
4730 #else
4731 				PassFunc = (IMA_GetTargetPropertiesFn)
4732 				    dlsym(plugintable[i].hPlugin,
4733 				    "IMA_GetTargetProperties");
4734 #endif
4735 
4736 				if (PassFunc != NULL) {
4737 					status = PassFunc(targetId, pProps);
4738 				}
4739 				os_releasemutex(plugintable[i].pluginMutex);
4740 			}
4741 
4742 			break;
4743 		}
4744 	}
4745 	os_releasemutex(libMutex);
4746 	return (status);
4747 }
4748 
4749 IMA_API	IMA_STATUS IMA_GetSessionProperties(
4750     IMA_OID sessionId,
4751     IMA_SESSION_PROPERTIES *pProps) {
4752 	IMA_GetSessionPropertiesFn PassFunc;
4753 	IMA_UINT i;
4754 	IMA_STATUS status;
4755 
4756 	if (number_of_plugins == -1)
4757 		InitLibrary();
4758 
4759 	if (pProps == NULL)
4760 		return (IMA_ERROR_INVALID_PARAMETER);
4761 
4762 	if (sessionId.objectType != IMA_OBJECT_TYPE_SESSION)
4763 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4764 
4765 	os_obtainmutex(libMutex);
4766 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4767 
4768 	for (i = 0; i < number_of_plugins; i++) {
4769 		if (plugintable[i].ownerId == sessionId.ownerId) {
4770 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4771 			if (plugintable[i].hPlugin != NULL) {
4772 				os_obtainmutex(plugintable[i].pluginMutex);
4773 #ifdef WIN32
4774 				PassFunc = (IMA_GetSessionPropertiesFn)
4775 				    GetProcAddress(plugintable[i].hPlugin,
4776 				    "IMA_GetSessionProperties");
4777 #else
4778 				PassFunc = (IMA_GetSessionPropertiesFn)
4779 				    dlsym(plugintable[i].hPlugin,
4780 				    "IMA_GetSessionProperties");
4781 #endif
4782 
4783 				if (PassFunc != NULL) {
4784 					status = PassFunc(sessionId, pProps);
4785 				}
4786 				os_releasemutex(plugintable[i].pluginMutex);
4787 			}
4788 
4789 			break;
4790 		}
4791 	}
4792 	os_releasemutex(libMutex);
4793 	return (status);
4794 }
4795 
4796 
4797 IMA_API	IMA_STATUS IMA_GetConnectionProperties(
4798     IMA_OID connectionId,
4799     IMA_CONNECTION_PROPERTIES *pProps) {
4800 	IMA_GetConnectionPropertiesFn PassFunc;
4801 	IMA_UINT i;
4802 	IMA_STATUS status;
4803 
4804 	if (number_of_plugins == -1)
4805 		InitLibrary();
4806 
4807 	if (pProps == NULL)
4808 		return (IMA_ERROR_INVALID_PARAMETER);
4809 
4810 	if (connectionId.objectType != IMA_OBJECT_TYPE_CONNECTION)
4811 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4812 
4813 	os_obtainmutex(libMutex);
4814 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4815 
4816 	for (i = 0; i < number_of_plugins; i++) {
4817 		if (plugintable[i].ownerId == connectionId.ownerId) {
4818 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4819 			if (plugintable[i].hPlugin != NULL) {
4820 				os_obtainmutex(plugintable[i].pluginMutex);
4821 #ifdef WIN32
4822 				PassFunc = (IMA_GetConnectionPropertiesFn)
4823 				    GetProcAddress(plugintable[i].hPlugin,
4824 				    "IMA_GetConnectionProperties");
4825 #else
4826 				PassFunc = (IMA_GetConnectionPropertiesFn)
4827 				    dlsym(plugintable[i].hPlugin,
4828 				    "IMA_GetConnectionProperties");
4829 #endif
4830 
4831 				if (PassFunc != NULL) {
4832 					status = PassFunc(connectionId, pProps);
4833 				}
4834 				os_releasemutex(plugintable[i].pluginMutex);
4835 			}
4836 
4837 			break;
4838 		}
4839 	}
4840 	os_releasemutex(libMutex);
4841 	return (status);
4842 }
4843 
4844 
4845 IMA_API IMA_STATUS IMA_GetTargetErrorStatistics(
4846     IMA_OID targetId,
4847     IMA_TARGET_ERROR_STATISTICS *pStats) {
4848 	IMA_GetTargetErrorStatisticsFn PassFunc;
4849 	IMA_UINT i;
4850 	IMA_STATUS status;
4851 
4852 	if (number_of_plugins == -1)
4853 		InitLibrary();
4854 
4855 	if (pStats == NULL)
4856 		return (IMA_ERROR_INVALID_PARAMETER);
4857 
4858 	if (targetId.objectType != IMA_OBJECT_TYPE_TARGET)
4859 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4860 
4861 	os_obtainmutex(libMutex);
4862 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4863 
4864 	for (i = 0; i < number_of_plugins; i++) {
4865 		if (plugintable[i].ownerId == targetId.ownerId) {
4866 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4867 			if (plugintable[i].hPlugin != NULL) {
4868 				os_obtainmutex(plugintable[i].pluginMutex);
4869 #ifdef WIN32
4870 				PassFunc = (IMA_GetTargetErrorStatisticsFn)
4871 				    GetProcAddress(plugintable[i].hPlugin,
4872 				    "IMA_GetTargetErrorStatistics");
4873 #else
4874 				PassFunc = (IMA_GetTargetErrorStatisticsFn)
4875 				    dlsym(plugintable[i].hPlugin,
4876 				    "IMA_GetTargetErrorStatistics");
4877 #endif
4878 
4879 				if (PassFunc != NULL) {
4880 					status = PassFunc(targetId, pStats);
4881 				}
4882 				os_releasemutex(plugintable[i].pluginMutex);
4883 			}
4884 
4885 			break;
4886 		}
4887 	}
4888 	os_releasemutex(libMutex);
4889 	return (status);
4890 }
4891 
4892 
4893 IMA_API IMA_STATUS IMA_GetLuOidList(
4894     IMA_OID Oid,
4895     IMA_OID_LIST **ppList) {
4896 	IMA_GetLuOidListFn PassFunc;
4897 	IMA_FreeMemoryFn FreeFunc;
4898 	IMA_UINT i;
4899 	IMA_STATUS status;
4900 
4901 	if (number_of_plugins == -1)
4902 		InitLibrary();
4903 
4904 	if (ppList == NULL)
4905 		return (IMA_ERROR_INVALID_PARAMETER);
4906 
4907 	if (Oid.objectType != IMA_OBJECT_TYPE_LHBA &&
4908 	    Oid.objectType != IMA_OBJECT_TYPE_TARGET)
4909 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4910 
4911 	os_obtainmutex(libMutex);
4912 	status = IMA_ERROR_OBJECT_NOT_FOUND;
4913 
4914 	for (i = 0; i < number_of_plugins; i++) {
4915 
4916 		if (plugintable[i].ownerId == Oid.ownerId) {
4917 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
4918 			if (plugintable[i].hPlugin != NULL) {
4919 				os_obtainmutex(plugintable[i].pluginMutex);
4920 #ifdef WIN32
4921 				PassFunc = (IMA_GetLuOidListFn)
4922 				    GetProcAddress(plugintable[i].hPlugin,
4923 				    "IMA_GetLuOidList");
4924 #else
4925 				PassFunc = (IMA_GetLuOidListFn)
4926 				    dlsym(plugintable[i].hPlugin,
4927 				    "IMA_GetLuOidList");
4928 #endif
4929 
4930 				if (PassFunc != NULL) {
4931 					IMA_OID_LIST *ppOidList;
4932 
4933 					status = PassFunc(Oid, &ppOidList);
4934 					if (IMA_SUCCESS(status)) {
4935 						IMA_UINT listSize;
4936 						listSize =
4937 						    sizeof (IMA_OID_LIST);
4938 						*ppList = (IMA_OID_LIST*)
4939 						    calloc(1, listSize +
4940 						    (ppOidList->oidCount - 1)*
4941 						    sizeof (IMA_OID));
4942 
4943 						if ((*ppList) == NULL) {
4944 							status = EUOS_ERROR;
4945 						}
4946 						else
4947 							memcpy((*ppList),
4948 							    ppOidList,
4949 							    listSize +
4950 							    (ppOidList->
4951 							    oidCount - 1)*
4952 							    sizeof (IMA_OID));
4953 #ifdef WIN32
4954 						FreeFunc = (IMA_FreeMemoryFn)
4955 						    GetProcAddress(
4956 						    plugintable[i].hPlugin,
4957 						    "IMA_FreeMemory");
4958 #else
4959 						FreeFunc = (IMA_FreeMemoryFn)
4960 						    dlsym(
4961 						    plugintable[i].hPlugin,
4962 						    "IMA_FreeMemory");
4963 #endif
4964 						if (FreeFunc != NULL) {
4965 							FreeFunc(ppOidList);
4966 						}
4967 					}
4968 				}
4969 				os_releasemutex(plugintable[i].pluginMutex);
4970 			}
4971 
4972 			break;
4973 		}
4974 	}
4975 	os_releasemutex(libMutex);
4976 	return (status);
4977 }
4978 
4979 
4980 IMA_API IMA_STATUS IMA_GetLuOid(
4981     IMA_OID targetId,
4982     IMA_UINT64 lun,
4983     IMA_OID *pluId) {
4984 	IMA_GetLuOidFn PassFunc;
4985 	IMA_UINT i;
4986 	IMA_STATUS status;
4987 
4988 	if (number_of_plugins == -1)
4989 		InitLibrary();
4990 
4991 	if (pluId == NULL)
4992 		return (IMA_ERROR_INVALID_PARAMETER);
4993 
4994 
4995 	if (targetId.objectType != IMA_OBJECT_TYPE_TARGET)
4996 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
4997 
4998 	os_obtainmutex(libMutex);
4999 		status = IMA_ERROR_OBJECT_NOT_FOUND;
5000 
5001 	for (i = 0; i < number_of_plugins; i++) {
5002 		if (plugintable[i].ownerId == targetId.ownerId) {
5003 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5004 			if (plugintable[i].hPlugin != NULL) {
5005 				os_obtainmutex(
5006 				    plugintable[i].pluginMutex);
5007 #ifdef WIN32
5008 				PassFunc = (IMA_GetLuOidFn)
5009 				    GetProcAddress(
5010 				    plugintable[i].hPlugin,
5011 				    "IMA_GetLuOid");
5012 #else
5013 				PassFunc = (IMA_GetLuOidFn)
5014 				    dlsym(plugintable[i].hPlugin,
5015 				    "IMA_GetLuOid");
5016 #endif
5017 
5018 				if (PassFunc != NULL) {
5019 					status =
5020 					    PassFunc(targetId, lun, pluId);
5021 				}
5022 				os_releasemutex(plugintable[i].pluginMutex);
5023 			}
5024 
5025 			break;
5026 		}
5027 	}
5028 	os_releasemutex(libMutex);
5029 	return (status);
5030 }
5031 
5032 
5033 IMA_API IMA_STATUS IMA_GetLuProperties(
5034     IMA_OID luId,
5035     IMA_LU_PROPERTIES *pProps) {
5036 	IMA_GetLuPropertiesFn PassFunc;
5037 	IMA_UINT i;
5038 	IMA_STATUS status;
5039 
5040 	if (number_of_plugins == -1)
5041 		InitLibrary();
5042 
5043 	if (pProps == NULL)
5044 		return (IMA_ERROR_INVALID_PARAMETER);
5045 
5046 	if (luId.objectType != IMA_OBJECT_TYPE_LU)
5047 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
5048 
5049 	os_obtainmutex(libMutex);
5050 	status = IMA_ERROR_OBJECT_NOT_FOUND;
5051 
5052 	for (i = 0; i < number_of_plugins; i++) {
5053 		if (plugintable[i].ownerId == luId.ownerId) {
5054 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5055 			if (plugintable[i].hPlugin != NULL) {
5056 				os_obtainmutex(plugintable[i].pluginMutex);
5057 #ifdef WIN32
5058 				PassFunc = (IMA_GetLuPropertiesFn)
5059 				    GetProcAddress(plugintable[i].hPlugin,
5060 				    "IMA_GetLuProperties");
5061 #else
5062 				PassFunc = (IMA_GetLuPropertiesFn)
5063 				    dlsym(plugintable[i].hPlugin,
5064 				    "IMA_GetLuProperties");
5065 #endif
5066 
5067 				if (PassFunc != NULL) {
5068 					status = PassFunc(luId, pProps);
5069 				}
5070 				os_releasemutex(plugintable[i].pluginMutex);
5071 			}
5072 
5073 			break;
5074 		}
5075 	}
5076 	os_releasemutex(libMutex);
5077 	return (status);
5078 }
5079 
5080 
5081 IMA_API IMA_STATUS IMA_GetStatisticsProperties(
5082     IMA_OID oid,
5083     IMA_STATISTICS_PROPERTIES *pProps) {
5084 	IMA_GetStatisticsPropertiesFn PassFunc;
5085 	IMA_UINT i;
5086 	IMA_STATUS status;
5087 
5088 	if (number_of_plugins == -1)
5089 		InitLibrary();
5090 
5091 	if (pProps == NULL)
5092 		return (IMA_ERROR_INVALID_PARAMETER);
5093 
5094 	if (oid.objectType != IMA_OBJECT_TYPE_TARGET &&
5095 	    oid.objectType != IMA_OBJECT_TYPE_LU &&
5096 	    oid.objectType != IMA_OBJECT_TYPE_PNP)
5097 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
5098 
5099 
5100 	os_obtainmutex(libMutex);
5101 	status = IMA_ERROR_OBJECT_NOT_FOUND;
5102 
5103 	for (i = 0; i < number_of_plugins; i++) {
5104 		if (plugintable[i].ownerId == oid.ownerId) {
5105 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5106 			if (plugintable[i].hPlugin != NULL) {
5107 				os_obtainmutex(plugintable[i].pluginMutex);
5108 #ifdef WIN32
5109 				PassFunc =
5110 				    (IMA_GetStatisticsPropertiesFn)
5111 				    GetProcAddress(plugintable[i].hPlugin,
5112 				    "IMA_GetStatisticsProperties");
5113 #else
5114 				PassFunc =
5115 				    (IMA_GetStatisticsPropertiesFn)
5116 				    dlsym(plugintable[i].hPlugin,
5117 				    "IMA_GetStatisticsProperties");
5118 #endif
5119 
5120 				if (PassFunc != NULL) {
5121 					status = PassFunc(oid, pProps);
5122 				}
5123 				os_releasemutex(plugintable[i].pluginMutex);
5124 			}
5125 
5126 			break;
5127 		}
5128 	}
5129 	os_releasemutex(libMutex);
5130 	return (status);
5131 }
5132 
5133 
5134 IMA_API IMA_STATUS IMA_GetDeviceStatistics(
5135     IMA_OID oid,
5136     IMA_DEVICE_STATISTICS *pStats) {
5137 	IMA_GetDeviceStatisticsFn PassFunc;
5138 	IMA_UINT i;
5139 	IMA_STATUS status;
5140 
5141 	if (number_of_plugins == -1)
5142 		InitLibrary();
5143 
5144 	if (pStats == NULL)
5145 		return (IMA_ERROR_INVALID_PARAMETER);
5146 
5147 	if (oid.objectType != IMA_OBJECT_TYPE_LU &&
5148 	    oid.objectType != IMA_OBJECT_TYPE_TARGET)
5149 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
5150 
5151 	os_obtainmutex(libMutex);
5152 	status = IMA_ERROR_OBJECT_NOT_FOUND;
5153 
5154 	for (i = 0; i < number_of_plugins; i++) {
5155 		if (plugintable[i].ownerId == oid.ownerId) {
5156 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5157 			if (plugintable[i].hPlugin != NULL) {
5158 				os_obtainmutex(plugintable[i].pluginMutex);
5159 #ifdef WIN32
5160 				PassFunc =
5161 				    (IMA_GetDeviceStatisticsFn)
5162 				    GetProcAddress(plugintable[i].hPlugin,
5163 				    "IMA_GetDeviceStatistics");
5164 #else
5165 				PassFunc =
5166 				    (IMA_GetDeviceStatisticsFn)
5167 				    dlsym(plugintable[i].hPlugin,
5168 				    "IMA_GetDeviceStatistics");
5169 #endif
5170 
5171 				if (PassFunc != NULL) {
5172 					status = PassFunc(oid, pStats);
5173 				}
5174 				os_releasemutex(plugintable[i].pluginMutex);
5175 			}
5176 
5177 			break;
5178 		}
5179 	}
5180 	os_releasemutex(libMutex);
5181 	return (status);
5182 }
5183 
5184 
5185 IMA_API IMA_STATUS IMA_LuInquiry(
5186     IMA_OID deviceId,
5187     IMA_BOOL evpd,
5188     IMA_BOOL cmddt,
5189     IMA_BYTE pageCode,
5190 
5191     IMA_BYTE *pOutputBuffer,
5192     IMA_UINT *pOutputBufferLength,
5193 
5194     IMA_BYTE *pSenseBuffer,
5195     IMA_UINT *pSenseBufferLength) {
5196 	IMA_LuInquiryFn PassFunc;
5197 	IMA_UINT i;
5198 	IMA_STATUS status;
5199 
5200 	if (number_of_plugins == -1)
5201 		InitLibrary();
5202 
5203 	if (pOutputBuffer == NULL || pOutputBufferLength == NULL ||
5204 	    *pOutputBufferLength == 0 ||
5205 	    pSenseBuffer == NULL || pSenseBufferLength == NULL ||
5206 	    *pSenseBufferLength == 0)
5207 		return (IMA_ERROR_INVALID_PARAMETER);
5208 
5209 	if ((evpd != IMA_TRUE && evpd != IMA_FALSE) ||
5210 	    (cmddt != IMA_TRUE && cmddt != IMA_FALSE))
5211 		return (IMA_ERROR_INVALID_PARAMETER);
5212 
5213 	if (deviceId.objectType != IMA_OBJECT_TYPE_TARGET &&
5214 	    deviceId.objectType != IMA_OBJECT_TYPE_LU)
5215 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
5216 
5217 	os_obtainmutex(libMutex);
5218 	status = IMA_ERROR_OBJECT_NOT_FOUND;
5219 
5220 	for (i = 0; i < number_of_plugins; i++) {
5221 		if (plugintable[i].ownerId == deviceId.ownerId) {
5222 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5223 			if (plugintable[i].hPlugin != NULL) {
5224 				os_obtainmutex(plugintable[i].pluginMutex);
5225 #ifdef WIN32
5226 				PassFunc = (IMA_LuInquiryFn)
5227 				    GetProcAddress(plugintable[i].hPlugin,
5228 				    "IMA_LuInquiry");
5229 #else
5230 				PassFunc = (IMA_LuInquiryFn)
5231 				    dlsym(plugintable[i].hPlugin,
5232 				    "IMA_LuInquiry");
5233 #endif
5234 
5235 				if (PassFunc != NULL) {
5236 					status =
5237 					    PassFunc(deviceId, evpd,
5238 					    cmddt, pageCode,
5239 					    pOutputBuffer, pOutputBufferLength,
5240 					    pSenseBuffer, pSenseBufferLength);
5241 				}
5242 				os_releasemutex(plugintable[i].pluginMutex);
5243 			}
5244 
5245 			break;
5246 		}
5247 	}
5248 	os_releasemutex(libMutex);
5249 	return (status);
5250 }
5251 
5252 
5253 IMA_API IMA_STATUS IMA_LuReadCapacity(
5254     IMA_OID deviceId,
5255     IMA_UINT cdbLength,
5256     IMA_BYTE *pOutputBuffer,
5257     IMA_UINT *pOutputBufferLength,
5258 
5259     IMA_BYTE *pSenseBuffer,
5260     IMA_UINT *pSenseBufferLength) {
5261 	IMA_LuReadCapacityFn PassFunc;
5262 	IMA_UINT i;
5263 	IMA_STATUS status;
5264 
5265 	if (number_of_plugins == -1)
5266 		InitLibrary();
5267 
5268 	if (cdbLength != 10 && cdbLength != 16)
5269 		return (IMA_ERROR_INVALID_PARAMETER);
5270 
5271 	if ((pOutputBuffer == NULL || pOutputBufferLength == NULL ||
5272 	    *pOutputBufferLength == 0) ||
5273 	    (pSenseBuffer == NULL && pSenseBufferLength != NULL &&
5274 	    *pSenseBufferLength != 0))
5275 		return (IMA_ERROR_INVALID_PARAMETER);
5276 
5277 	if (deviceId.objectType != IMA_OBJECT_TYPE_TARGET &&
5278 	    deviceId.objectType != IMA_OBJECT_TYPE_LU)
5279 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
5280 
5281 	os_obtainmutex(libMutex);
5282 	status = IMA_ERROR_OBJECT_NOT_FOUND;
5283 
5284 	for (i = 0; i < number_of_plugins; i++) {
5285 		if (plugintable[i].ownerId == deviceId.ownerId) {
5286 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5287 			if (plugintable[i].hPlugin != NULL) {
5288 				os_obtainmutex(plugintable[i].pluginMutex);
5289 #ifdef WIN32
5290 				PassFunc = (IMA_LuReadCapacityFn)
5291 				    GetProcAddress(plugintable[i].hPlugin,
5292 				    "IMA_LuReadCapacity");
5293 #else
5294 				PassFunc = (IMA_LuReadCapacityFn)
5295 				    dlsym(plugintable[i].hPlugin,
5296 				    "IMA_LuReadCapacity");
5297 #endif
5298 
5299 				if (PassFunc != NULL) {
5300 					status = PassFunc(deviceId, cdbLength,
5301 					    pOutputBuffer, pOutputBufferLength,
5302 					    pSenseBuffer, pSenseBufferLength);
5303 				}
5304 				os_releasemutex(plugintable[i].pluginMutex);
5305 			}
5306 
5307 			break;
5308 		}
5309 	}
5310 	os_releasemutex(libMutex);
5311 	return (status);
5312 }
5313 
5314 
5315 IMA_API IMA_STATUS IMA_LuReportLuns(
5316     IMA_OID deviceId,
5317     IMA_BOOL sendToWellKnownLun,
5318     IMA_BYTE selectReport,
5319 
5320     IMA_BYTE *pOutputBuffer,
5321     IMA_UINT *pOutputBufferLength,
5322 
5323     IMA_BYTE *pSenseBuffer,
5324     IMA_UINT *pSenseBufferLength) {
5325 	IMA_LuReportLunsFn PassFunc;
5326 	IMA_UINT i;
5327 	IMA_STATUS status;
5328 
5329 	if (number_of_plugins == -1)
5330 		InitLibrary();
5331 
5332 	if ((pOutputBuffer == NULL || pOutputBufferLength == NULL ||
5333 	    *pOutputBufferLength == 0) ||
5334 	    (pSenseBuffer == NULL && pSenseBufferLength != NULL &&
5335 	    *pSenseBufferLength != 0))
5336 		return (IMA_ERROR_INVALID_PARAMETER);
5337 
5338 	if (sendToWellKnownLun != IMA_TRUE && sendToWellKnownLun != IMA_FALSE)
5339 		return (IMA_ERROR_INVALID_PARAMETER);
5340 
5341 	if (deviceId.objectType != IMA_OBJECT_TYPE_TARGET &&
5342 	    deviceId.objectType != IMA_OBJECT_TYPE_LU)
5343 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
5344 
5345 	os_obtainmutex(libMutex);
5346 	status = IMA_ERROR_OBJECT_NOT_FOUND;
5347 
5348 	for (i = 0; i < number_of_plugins; i++) {
5349 		if (plugintable[i].ownerId == deviceId.ownerId) {
5350 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5351 			if (plugintable[i].hPlugin != NULL) {
5352 				os_obtainmutex(plugintable[i].pluginMutex);
5353 #ifdef WIN32
5354 				PassFunc = (IMA_LuReportLunsFn)
5355 				    GetProcAddress(plugintable[i].hPlugin,
5356 				    "IMA_LuReportLuns");
5357 #else
5358 				PassFunc = (IMA_LuReportLunsFn)
5359 				    dlsym(plugintable[i].hPlugin,
5360 				    "IMA_LuReportLuns");
5361 #endif
5362 
5363 				if (PassFunc != NULL) {
5364 					status = PassFunc(deviceId,
5365 					    sendToWellKnownLun, selectReport,
5366 					    pOutputBuffer, pOutputBufferLength,
5367 					    pSenseBuffer, pSenseBufferLength);
5368 				}
5369 				os_releasemutex(plugintable[i].pluginMutex);
5370 			}
5371 
5372 			break;
5373 		}
5374 	}
5375 	os_releasemutex(libMutex);
5376 	return (status);
5377 }
5378 
5379 IMA_API IMA_STATUS IMA_ExposeLu(
5380     IMA_OID luId) {
5381 	IMA_ExposeLuFn PassFunc;
5382 	IMA_UINT i;
5383 	IMA_STATUS status;
5384 
5385 	if (number_of_plugins == -1)
5386 		InitLibrary();
5387 
5388 	if (luId.objectType != IMA_OBJECT_TYPE_LU)
5389 		return (IMA_ERROR_INVALID_OBJECT_TYPE);
5390 
5391 	os_obtainmutex(libMutex);
5392 	status = IMA_ERROR_OBJECT_NOT_FOUND;
5393 
5394 	for (i = 0; i < number_of_plugins; i++) {
5395 		if (plugintable[i].ownerId == luId.ownerId) {
5396 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5397 			if (plugintable[i].hPlugin != NULL) {
5398 				os_obtainmutex(plugintable[i].pluginMutex);
5399 #ifdef WIN32
5400 				PassFunc = (IMA_ExposeLuFn)
5401 				    GetProcAddress(plugintable[i].hPlugin,
5402 				    "IMA_ExposeLu");
5403 
5404 #else
5405 				PassFunc = (IMA_ExposeLuFn)
5406 				    dlsym(plugintable[i].hPlugin,
5407 				    "IMA_ExposeLu");
5408 #endif
5409 
5410 				if (PassFunc != NULL) {
5411 					status = PassFunc(luId);
5412 				}
5413 				os_releasemutex(plugintable[i].pluginMutex);
5414 			}
5415 
5416 			break;
5417 		}
5418 	}
5419 	os_releasemutex(libMutex);
5420 	return (status);
5421 }
5422 
5423 
5424 IMA_API IMA_STATUS IMA_UnexposeLu(
5425     IMA_OID luId) {
5426 	IMA_UnexposeLuFn PassFunc;
5427 	IMA_UINT i;
5428 	IMA_STATUS status;
5429 
5430 	if (number_of_plugins == -1)
5431 		InitLibrary();
5432 
5433 	if (luId.objectType != IMA_OBJECT_TYPE_LU)
5434 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
5435 
5436 	os_obtainmutex(libMutex);
5437 	status = IMA_ERROR_OBJECT_NOT_FOUND;
5438 
5439 	for (i = 0; i < number_of_plugins; i++) {
5440 		if (plugintable[i].ownerId == luId.ownerId) {
5441 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5442 			if (plugintable[i].hPlugin != NULL) {
5443 				os_obtainmutex(plugintable[i].pluginMutex);
5444 #ifdef WIN32
5445 				PassFunc = (IMA_UnexposeLuFn)
5446 				    GetProcAddress(plugintable[i].hPlugin,
5447 				    "IMA_UnexposeLu");
5448 #else
5449 				PassFunc = (IMA_UnexposeLuFn)
5450 				    dlsym(plugintable[i].hPlugin,
5451 				    "IMA_UnexposeLu");
5452 #endif
5453 
5454 				if (PassFunc != NULL) {
5455 					status = PassFunc(luId);
5456 				}
5457 				os_releasemutex(plugintable[i].pluginMutex);
5458 			}
5459 
5460 			break;
5461 		}
5462 	}
5463 	os_releasemutex(libMutex);
5464 	return (status);
5465 }
5466 
5467 
5468 IMA_API IMA_STATUS IMA_GetPhbaStatus(
5469     IMA_OID hbaId,
5470     IMA_PHBA_STATUS *pStatus) {
5471 	IMA_GetPhbaStatusFn PassFunc;
5472 	IMA_UINT i;
5473 	IMA_STATUS status;
5474 
5475 	if (number_of_plugins == -1)
5476 		InitLibrary();
5477 
5478 	if (pStatus == NULL)
5479 		return (IMA_ERROR_INVALID_PARAMETER);
5480 
5481 	if (hbaId.objectType != IMA_OBJECT_TYPE_PHBA)
5482 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
5483 
5484 	os_obtainmutex(libMutex);
5485 	status = IMA_ERROR_OBJECT_NOT_FOUND;
5486 
5487 	for (i = 0; i < number_of_plugins; i++) {
5488 		if (plugintable[i].ownerId == hbaId.ownerId) {
5489 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5490 			if (plugintable[i].hPlugin != NULL) {
5491 				os_obtainmutex(plugintable[i].pluginMutex);
5492 #ifdef WIN32
5493 				PassFunc = (IMA_GetPhbaStatusFn)
5494 				    GetProcAddress(plugintable[i].hPlugin,
5495 				    "IMA_GetPhbaStatus");
5496 #else
5497 				PassFunc = (IMA_GetPhbaStatusFn)
5498 				    dlsym(plugintable[i].hPlugin,
5499 				    "IMA_GetPhbaStatus");
5500 #endif
5501 
5502 				if (PassFunc != NULL) {
5503 					status = PassFunc(hbaId, pStatus);
5504 				}
5505 				os_releasemutex(plugintable[i].pluginMutex);
5506 			}
5507 
5508 			break;
5509 		}
5510 	}
5511 	os_releasemutex(libMutex);
5512 	return (status);
5513 }
5514 
5515 
5516 IMA_API IMA_STATUS IMA_RegisterForObjectVisibilityChanges(
5517     IMA_OBJECT_VISIBILITY_FN pClientFn) {
5518 	IMA_RegisterForObjectVisibilityChangesFn PassFunc;
5519 	IMA_UINT i;
5520 	IMA_UINT j;
5521 	IMA_STATUS status;
5522 
5523 	if (number_of_plugins == -1)
5524 		InitLibrary();
5525 
5526 	if (pClientFn == NULL)
5527 		return (IMA_ERROR_INVALID_PARAMETER);
5528 
5529 	os_obtainmutex(libMutex);
5530 
5531 	status = IMA_STATUS_SUCCESS;
5532 	for (i = 0; i < number_of_plugins; i++) {
5533 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5534 		if (plugintable[i].hPlugin != NULL) {
5535 			os_obtainmutex(plugintable[i].pluginMutex);
5536 			if (plugintable[i].number_of_vbcallbacks >=
5537 			    IMA_MAX_CALLBACK_PER_PLUGIN) {
5538 				os_releasemutex(plugintable[i].pluginMutex);
5539 				continue;
5540 			}
5541 
5542 			/* check if registered already */
5543 			for (j = 0;
5544 			    j < plugintable[i].number_of_vbcallbacks; j++) {
5545 				if (plugintable[i].vbcallback[j] == pClientFn) {
5546 					status = IMA_STATUS_SUCCESS;
5547 					break;
5548 				}
5549 			}
5550 			if (status != IMA_STATUS_SUCCESS) {
5551 
5552 #ifdef WIN32
5553 				PassFunc =
5554 				    (IMA_RegisterForObjectVisibilityChangesFn)
5555 				    GetProcAddress(plugintable[i].hPlugin,
5556 				    "IMA_RegisterForObjectVisibilityChanges");
5557 #else
5558 				PassFunc =
5559 				    (IMA_RegisterForObjectVisibilityChangesFn)
5560 				    dlsym(plugintable[i].hPlugin,
5561 				    "IMA_RegisterForObjectVisibilityChanges");
5562 #endif
5563 
5564 				if (PassFunc != NULL) {
5565 					status = PassFunc(VisibilityCallback);
5566 					if (status == IMA_STATUS_SUCCESS) {
5567 						j = plugintable[i].
5568 						    number_of_vbcallbacks;
5569 						plugintable[i].vbcallback[j] =
5570 						    pClientFn;
5571 						plugintable[i].
5572 						    number_of_vbcallbacks++;
5573 					}
5574 
5575 				}
5576 			}
5577 			os_releasemutex(plugintable[i].pluginMutex);
5578 		}
5579 		if (status != IMA_STATUS_SUCCESS)
5580 			break;
5581 
5582 	}
5583 	os_releasemutex(libMutex);
5584 	return (status);
5585 
5586 }
5587 
5588 
5589 IMA_API IMA_STATUS IMA_DeregisterForObjectVisibilityChanges(
5590     IMA_OBJECT_VISIBILITY_FN pClientFn) {
5591 	IMA_DeregisterForObjectVisibilityChangesFn PassFunc;
5592 	IMA_UINT i;
5593 	IMA_UINT j;
5594 	IMA_STATUS status;
5595 
5596 	if (number_of_plugins == -1)
5597 		InitLibrary();
5598 
5599 	if (pClientFn == NULL)
5600 		return (IMA_ERROR_INVALID_PARAMETER);
5601 
5602 	os_obtainmutex(libMutex);
5603 
5604 	status = IMA_STATUS_SUCCESS;
5605 	for (i = 0; i < number_of_plugins; i++) {
5606 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5607 		if (plugintable[i].hPlugin != NULL) {
5608 			os_obtainmutex(plugintable[i].pluginMutex);
5609 			/* check if deregistered already */
5610 			status = IMA_STATUS_SUCCESS;
5611 			for (j = 0;
5612 			    j < plugintable[i].number_of_vbcallbacks; j++) {
5613 				if (plugintable[i].vbcallback[j] == pClientFn) {
5614 					/*
5615 					 * use IMA_ERROR_UNKNOWN_ERROR
5616 					 * as a flag
5617 					 */
5618 					status = IMA_ERROR_UNKNOWN_ERROR;
5619 					break;
5620 				}
5621 			}
5622 
5623 			if (status != IMA_STATUS_SUCCESS) {
5624 
5625 #ifdef WIN32
5626 				PassFunc =
5627 				    (IMA_DeregisterForObjectVisibilityChangesFn)
5628 				    GetProcAddress(plugintable[i].hPlugin,
5629 				    "IMA_DeregisterForObjectVisibilityChanges");
5630 #else
5631 				PassFunc =
5632 				    (IMA_DeregisterForObjectVisibilityChangesFn)
5633 				    dlsym(plugintable[i].hPlugin,
5634 				    "IMA_DeregisterForObjectVisibilityChanges");
5635 #endif
5636 				if (PassFunc != NULL) {
5637 					status = PassFunc(VisibilityCallback);
5638 					if (status == IMA_STATUS_SUCCESS) {
5639 						/*
5640 						 * where plugintable[i].
5641 						 * vbcallback[j] == pClientFn
5642 						 */
5643 						for (; j <
5644 						    plugintable[i].
5645 						    number_of_vbcallbacks;
5646 						    j++) {
5647 							plugintable[i].
5648 							    vbcallback[j] =
5649 							    plugintable[i].
5650 							    vbcallback[j+1];
5651 
5652 						}
5653 						plugintable[i].
5654 						    number_of_vbcallbacks--;
5655 					}
5656 				}
5657 			}
5658 			os_releasemutex(plugintable[i].pluginMutex);
5659 		}
5660 		if (status != IMA_STATUS_SUCCESS)
5661 			break;
5662 	}
5663 	os_releasemutex(libMutex);
5664 	return (status);
5665 
5666 }
5667 
5668 
5669 IMA_API IMA_STATUS IMA_RegisterForObjectPropertyChanges(
5670     IMA_OBJECT_PROPERTY_FN pClientFn) {
5671 	IMA_RegisterForObjectPropertyChangesFn PassFunc;
5672 	IMA_UINT i;
5673 	IMA_UINT j;
5674 	IMA_STATUS status;
5675 
5676 	if (number_of_plugins == -1)
5677 		InitLibrary();
5678 
5679 	if (pClientFn == NULL)
5680 		return (IMA_ERROR_INVALID_PARAMETER);
5681 
5682 	os_obtainmutex(libMutex);
5683 
5684 	status = IMA_STATUS_SUCCESS;
5685 	for (i = 0; i < number_of_plugins; i++) {
5686 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5687 		if (plugintable[i].hPlugin != NULL) {
5688 			os_obtainmutex(plugintable[i].pluginMutex);
5689 			if (plugintable[i].number_of_pccallbacks >=
5690 			    IMA_MAX_CALLBACK_PER_PLUGIN) {
5691 				os_releasemutex(plugintable[i].pluginMutex);
5692 				continue;
5693 			}
5694 
5695 			/* check if registered already */
5696 			for (j = 0;
5697 			    j < plugintable[i].number_of_pccallbacks;
5698 			    j++) {
5699 				if (plugintable[i].pccallback[j] ==
5700 				    pClientFn) {
5701 					status = IMA_STATUS_SUCCESS;
5702 					break;
5703 				}
5704 			}
5705 			if (status != IMA_STATUS_SUCCESS) {
5706 
5707 #ifdef WIN32
5708 				PassFunc =
5709 				    (IMA_RegisterForObjectPropertyChangesFn)
5710 				    GetProcAddress(plugintable[i].hPlugin,
5711 				    "IMA_RegisterForObjectPropertyChanges");
5712 #else
5713 				PassFunc =
5714 				    (IMA_RegisterForObjectPropertyChangesFn)
5715 				    dlsym(plugintable[i].hPlugin,
5716 				    "IMA_RegisterForObjectPropertyChanges");
5717 #endif
5718 
5719 				if (PassFunc != NULL) {
5720 					status = PassFunc(PropertyCallback);
5721 					if (status == IMA_STATUS_SUCCESS) {
5722 						j = plugintable[i].
5723 						    number_of_pccallbacks;
5724 						plugintable[i].pccallback[j] =
5725 						    pClientFn;
5726 						plugintable[i].
5727 						    number_of_pccallbacks++;
5728 					}
5729 
5730 				}
5731 			}
5732 			os_releasemutex(plugintable[i].pluginMutex);
5733 		}
5734 		if (status != IMA_STATUS_SUCCESS)
5735 			break;
5736 
5737 	}
5738 	os_releasemutex(libMutex);
5739 	return (status);
5740 
5741 }
5742 
5743 
5744 IMA_API IMA_STATUS IMA_DeregisterForObjectPropertyChanges(
5745     IMA_OBJECT_PROPERTY_FN pClientFn) {
5746 	IMA_DeregisterForObjectPropertyChangesFn PassFunc;
5747 	IMA_UINT i;
5748 	IMA_UINT j;
5749 	IMA_STATUS status;
5750 
5751 	if (number_of_plugins == -1)
5752 		InitLibrary();
5753 
5754 	if (pClientFn == NULL)
5755 		return (IMA_ERROR_INVALID_PARAMETER);
5756 
5757 	os_obtainmutex(libMutex);
5758 	status = IMA_STATUS_SUCCESS;
5759 	for (i = 0; i < number_of_plugins; i++) {
5760 		status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5761 		if (plugintable[i].hPlugin != NULL) {
5762 			os_obtainmutex(plugintable[i].pluginMutex);
5763 			/* check if deregistered already */
5764 			status = IMA_STATUS_SUCCESS;
5765 			for (j = 0;
5766 			    j < plugintable[i].number_of_pccallbacks;
5767 			    j++) {
5768 				if (plugintable[i].pccallback[j] ==
5769 				    pClientFn) {
5770 					/*
5771 					 * use IMA_ERROR_UNKNOWN_ERROR
5772 					 * as a flag
5773 					 */
5774 					status = IMA_ERROR_UNKNOWN_ERROR;
5775 					break;
5776 				}
5777 			}
5778 
5779 			if (status != IMA_STATUS_SUCCESS) {
5780 
5781 #ifdef WIN32
5782 				PassFunc =
5783 				    (IMA_DeregisterForObjectPropertyChangesFn)
5784 				    GetProcAddress(plugintable[i].hPlugin,
5785 				    "IMA_DeregisterForObjectPropertyChanges");
5786 
5787 #else
5788 				PassFunc =
5789 				    (IMA_DeregisterForObjectPropertyChangesFn)
5790 				    dlsym(plugintable[i].hPlugin,
5791 				    "IMA_DeregisterForObjectPropertyChanges");
5792 #endif
5793 
5794 				if (PassFunc != NULL) {
5795 					status = PassFunc(PropertyCallback);
5796 					if (status == IMA_STATUS_SUCCESS) {
5797 					/*
5798 					 * where plugintable[i].vbcallback[
5799 					 * j] == pClientFn
5800 					 */
5801 						for (; j < plugintable[i].
5802 						    number_of_pccallbacks;
5803 						    j++) {
5804 							plugintable[i].
5805 							    pccallback[j]
5806 							    = plugintable[i].
5807 							    pccallback[j+1];
5808 
5809 						}
5810 						plugintable[i].
5811 						    number_of_pccallbacks--;
5812 					}
5813 
5814 				}
5815 			}
5816 			os_releasemutex(plugintable[i].pluginMutex);
5817 		}
5818 		if (status != IMA_STATUS_SUCCESS)
5819 			break;
5820 
5821 	}
5822 	os_releasemutex(libMutex);
5823 	return (status);
5824 
5825 }
5826 
5827 
5828 IMA_API IMA_STATUS IMA_GetIpProperties(
5829     IMA_OID oid,
5830     IMA_IP_PROPERTIES *pProps) {
5831 	IMA_GetIpPropertiesFn PassFunc;
5832 	IMA_UINT i;
5833 	IMA_STATUS status;
5834 
5835 	if (number_of_plugins == -1)
5836 		InitLibrary();
5837 
5838 	if (pProps == NULL)
5839 		return (IMA_ERROR_INVALID_PARAMETER);
5840 
5841 	if (oid.objectType != IMA_OBJECT_TYPE_PNP)
5842 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
5843 
5844 	os_obtainmutex(libMutex);
5845 	status = IMA_ERROR_OBJECT_NOT_FOUND;
5846 
5847 	for (i = 0; i < number_of_plugins; i++) {
5848 		if (plugintable[i].ownerId == oid.ownerId) {
5849 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5850 			if (plugintable[i].hPlugin != NULL) {
5851 				os_obtainmutex(plugintable[i].pluginMutex);
5852 #ifdef WIN32
5853 				PassFunc = (IMA_GetIpPropertiesFn)
5854 				    GetProcAddress(plugintable[i].hPlugin,
5855 				    "IMA_GetIpProperties");
5856 #else
5857 				PassFunc = (IMA_GetIpPropertiesFn)
5858 				    dlsym(plugintable[i].hPlugin,
5859 				    "IMA_GetIpProperties");
5860 #endif
5861 				if (PassFunc != NULL) {
5862 					status = PassFunc(oid, pProps);
5863 				}
5864 				os_releasemutex(plugintable[i].pluginMutex);
5865 			}
5866 
5867 			break;
5868 		}
5869 	}
5870 	os_releasemutex(libMutex);
5871 	return (status);
5872 }
5873 
5874 
5875 IMA_API IMA_STATUS IMA_SetIpConfigMethod(
5876     IMA_OID oid,
5877     IMA_BOOL enableDhcpIpConfiguration) {
5878 	IMA_SetIpConfigMethodFn PassFunc;
5879 	IMA_UINT i;
5880 	IMA_STATUS status;
5881 
5882 	if (number_of_plugins == -1)
5883 		InitLibrary();
5884 
5885 	if (enableDhcpIpConfiguration != IMA_TRUE &&
5886 	    enableDhcpIpConfiguration != IMA_FALSE)
5887 		return (IMA_ERROR_INVALID_PARAMETER);
5888 
5889 	if (oid.objectType != IMA_OBJECT_TYPE_PNP)
5890 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
5891 
5892 	os_obtainmutex(libMutex);
5893 	status = IMA_ERROR_OBJECT_NOT_FOUND;
5894 
5895 	for (i = 0; i < number_of_plugins; i++) {
5896 		if (plugintable[i].ownerId == oid.ownerId) {
5897 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5898 			if (plugintable[i].hPlugin != NULL) {
5899 				os_obtainmutex(plugintable[i].pluginMutex);
5900 #ifdef WIN32
5901 				PassFunc = (IMA_SetIpConfigMethodFn)
5902 				    GetProcAddress(plugintable[i].hPlugin,
5903 				    "IMA_SetIpConfigMethod");
5904 #else
5905 				PassFunc = (IMA_SetIpConfigMethodFn)
5906 				    dlsym(plugintable[i].hPlugin,
5907 				    "IMA_SetIpConfigMethod");
5908 #endif
5909 
5910 				if (PassFunc != NULL) {
5911 					status = PassFunc(oid,
5912 					    enableDhcpIpConfiguration);
5913 				}
5914 				os_releasemutex(plugintable[i].pluginMutex);
5915 			}
5916 
5917 			break;
5918 		}
5919 	}
5920 	os_releasemutex(libMutex);
5921 	return (status);
5922 }
5923 
5924 IMA_API IMA_STATUS IMA_SetSubnetMask(
5925     IMA_OID oid,
5926     IMA_IP_ADDRESS subnetMask) {
5927 	IMA_SetSubnetMaskFn PassFunc;
5928 	IMA_UINT i;
5929 	IMA_STATUS status;
5930 
5931 	if (number_of_plugins == -1)
5932 		InitLibrary();
5933 
5934 	if (oid.objectType != IMA_OBJECT_TYPE_PNP)
5935 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
5936 
5937 	os_obtainmutex(libMutex);
5938 	status = IMA_ERROR_OBJECT_NOT_FOUND;
5939 
5940 	for (i = 0; i < number_of_plugins; i++) {
5941 		if (plugintable[i].ownerId == oid.ownerId) {
5942 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
5943 			if (plugintable[i].hPlugin != NULL) {
5944 				os_obtainmutex(plugintable[i].pluginMutex);
5945 #ifdef WIN32
5946 				PassFunc = (IMA_SetSubnetMaskFn)
5947 				    GetProcAddress(plugintable[i].hPlugin,
5948 				    "IMA_SetSubnetMask");
5949 #else
5950 				PassFunc = (IMA_SetSubnetMaskFn)
5951 				    dlsym(plugintable[i].hPlugin,
5952 				    "IMA_SetSubnetMask");
5953 #endif
5954 
5955 				if (PassFunc != NULL) {
5956 					status = PassFunc(oid, subnetMask);
5957 				}
5958 				os_releasemutex(plugintable[i].pluginMutex);
5959 			}
5960 
5961 			break;
5962 		}
5963 	}
5964 	os_releasemutex(libMutex);
5965 	return (status);
5966 }
5967 
5968 
5969 IMA_API IMA_STATUS IMA_SetDnsServerAddress(
5970     IMA_OID oid,
5971     const IMA_IP_ADDRESS *primaryDnsServerAddress,
5972     const IMA_IP_ADDRESS *alternateDnsServerAddress) {
5973 	IMA_SetDnsServerAddressFn PassFunc;
5974 	IMA_UINT i;
5975 	IMA_STATUS status;
5976 
5977 	if (number_of_plugins == -1)
5978 		InitLibrary();
5979 
5980 	if (primaryDnsServerAddress == NULL &&
5981 	    alternateDnsServerAddress != NULL)
5982 		return (IMA_ERROR_INVALID_PARAMETER);
5983 
5984 	if (primaryDnsServerAddress != NULL &&
5985 	    alternateDnsServerAddress != NULL &&
5986 	    memcmp(primaryDnsServerAddress->ipAddress,
5987 	    alternateDnsServerAddress->ipAddress,
5988 	    sizeof (primaryDnsServerAddress->ipAddress)) == 0)
5989 		return (IMA_ERROR_INVALID_PARAMETER);
5990 
5991 	if (oid.objectType != IMA_OBJECT_TYPE_PNP)
5992 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
5993 
5994 	os_obtainmutex(libMutex);
5995 	status = IMA_ERROR_OBJECT_NOT_FOUND;
5996 
5997 	for (i = 0; i < number_of_plugins; i++) {
5998 		if (plugintable[i].ownerId == oid.ownerId) {
5999 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6000 			if (plugintable[i].hPlugin != NULL) {
6001 				os_obtainmutex(plugintable[i].pluginMutex);
6002 #ifdef WIN32
6003 				PassFunc = (IMA_SetDnsServerAddressFn)
6004 				    GetProcAddress(plugintable[i].hPlugin,
6005 				    "IMA_SetDnsServerAddress");
6006 #else
6007 				PassFunc = (IMA_SetDnsServerAddressFn)
6008 				    dlsym(plugintable[i].hPlugin,
6009 				    "IMA_SetDnsServerAddress");
6010 #endif
6011 
6012 				if (PassFunc != NULL) {
6013 					status = PassFunc(oid,
6014 					    primaryDnsServerAddress,
6015 					    alternateDnsServerAddress);
6016 				}
6017 				os_releasemutex(plugintable[i].pluginMutex);
6018 			}
6019 
6020 			break;
6021 		}
6022 	}
6023 	os_releasemutex(libMutex);
6024 	return (status);
6025 }
6026 
6027 
6028 IMA_API IMA_STATUS IMA_SetDefaultGateway(
6029     IMA_OID oid,
6030     IMA_IP_ADDRESS defaultGateway) {
6031 	IMA_SetDefaultGatewayFn PassFunc;
6032 	IMA_UINT i;
6033 	IMA_STATUS status;
6034 
6035 	if (number_of_plugins == -1)
6036 		InitLibrary();
6037 
6038 	if (oid.objectType != IMA_OBJECT_TYPE_PNP)
6039 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6040 
6041 	os_obtainmutex(libMutex);
6042 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6043 
6044 	for (i = 0; i < number_of_plugins; i++) {
6045 		if (plugintable[i].ownerId == oid.ownerId) {
6046 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6047 			if (plugintable[i].hPlugin != NULL) {
6048 				os_obtainmutex(plugintable[i].pluginMutex);
6049 #ifdef WIN32
6050 				PassFunc = (IMA_SetDefaultGatewayFn)
6051 				    GetProcAddress(plugintable[i].hPlugin,
6052 				    "IMA_SetDefaultGateway");
6053 #else
6054 				PassFunc = (IMA_SetDefaultGatewayFn)
6055 				    dlsym(plugintable[i].hPlugin,
6056 				    "IMA_SetDefaultGateway");
6057 #endif
6058 
6059 				if (PassFunc != NULL) {
6060 					status = PassFunc(oid, defaultGateway);
6061 				}
6062 				os_releasemutex(plugintable[i].pluginMutex);
6063 			}
6064 
6065 			break;
6066 		}
6067 	}
6068 	os_releasemutex(libMutex);
6069 	return (status);
6070 }
6071 
6072 
6073 IMA_API IMA_STATUS IMA_GetSupportedAuthMethods(
6074     IMA_OID lhbaOid,
6075     IMA_BOOL getSettableMethods,
6076     IMA_UINT *pMethodCount,
6077     IMA_AUTHMETHOD *pMethodList) {
6078 	IMA_GetSupportedAuthMethodsFn PassFunc;
6079 	IMA_UINT i;
6080 	IMA_STATUS status;
6081 
6082 	if (number_of_plugins == -1)
6083 		InitLibrary();
6084 
6085 	if (pMethodCount == NULL)
6086 		return (IMA_ERROR_INVALID_PARAMETER);
6087 
6088 	if (lhbaOid.objectType != IMA_OBJECT_TYPE_LHBA)
6089 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6090 
6091 	os_obtainmutex(libMutex);
6092 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6093 
6094 	for (i = 0; i < number_of_plugins; i++) {
6095 		if (plugintable[i].ownerId == lhbaOid.ownerId) {
6096 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6097 			if (plugintable[i].hPlugin != NULL) {
6098 				os_obtainmutex(plugintable[i].pluginMutex);
6099 #ifdef WIN32
6100 				PassFunc = (IMA_GetSupportedAuthMethodsFn)
6101 				    GetProcAddress(plugintable[i].hPlugin,
6102 				    "IMA_GetSupportedAuthMethods");
6103 #else
6104 				PassFunc = (IMA_GetSupportedAuthMethodsFn)
6105 				    dlsym(plugintable[i].hPlugin,
6106 				    "IMA_GetSupportedAuthMethods");
6107 #endif
6108 
6109 				if (PassFunc != NULL) {
6110 					status = PassFunc(lhbaOid,
6111 					    getSettableMethods,
6112 					    pMethodCount, pMethodList);
6113 				}
6114 				os_releasemutex(plugintable[i].pluginMutex);
6115 			}
6116 
6117 			break;
6118 		}
6119 	}
6120 	os_releasemutex(libMutex);
6121 	return (status);
6122 }
6123 
6124 
6125 IMA_API IMA_STATUS IMA_GetInUseInitiatorAuthMethods(
6126     IMA_OID lhbaOid,
6127     IMA_UINT *pMethodCount,
6128     IMA_AUTHMETHOD *pMethodList) {
6129 	IMA_GetInUseInitiatorAuthMethodsFn PassFunc;
6130 	IMA_UINT i;
6131 	IMA_STATUS status;
6132 
6133 	if (number_of_plugins == -1)
6134 		InitLibrary();
6135 
6136 	if (pMethodCount == NULL)
6137 		return (IMA_ERROR_INVALID_PARAMETER);
6138 
6139 	if (lhbaOid.objectType != IMA_OBJECT_TYPE_LHBA)
6140 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6141 
6142 	os_obtainmutex(libMutex);
6143 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6144 
6145 	for (i = 0; i < number_of_plugins; i++) {
6146 		if (plugintable[i].ownerId == lhbaOid.ownerId) {
6147 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6148 			if (plugintable[i].hPlugin != NULL) {
6149 				os_obtainmutex(plugintable[i].pluginMutex);
6150 #ifdef WIN32
6151 				PassFunc = (IMA_GetInUseInitiatorAuthMethodsFn)
6152 				    GetProcAddress(plugintable[i].hPlugin,
6153 				    "IMA_GetInUseInitiatorAuthMethods");
6154 #else
6155 				PassFunc = (IMA_GetInUseInitiatorAuthMethodsFn)
6156 				    dlsym(plugintable[i].hPlugin,
6157 				    "IMA_GetInUseInitiatorAuthMethods");
6158 #endif
6159 
6160 				if (PassFunc != NULL) {
6161 					status = PassFunc(lhbaOid,
6162 					    pMethodCount, pMethodList);
6163 				}
6164 				os_releasemutex(plugintable[i].pluginMutex);
6165 			}
6166 
6167 			break;
6168 		}
6169 	}
6170 	os_releasemutex(libMutex);
6171 	return (status);
6172 }
6173 
6174 
6175 IMA_API IMA_STATUS IMA_GetInitiatorAuthParms(
6176     IMA_OID lhbaOid,
6177     IMA_AUTHMETHOD method,
6178     IMA_INITIATOR_AUTHPARMS *pParms) {
6179 	IMA_GetInitiatorAuthParmsFn PassFunc;
6180 	IMA_UINT i;
6181 	IMA_STATUS status;
6182 
6183 	if (number_of_plugins == -1)
6184 		InitLibrary();
6185 
6186 	if (pParms == NULL)
6187 		return (IMA_ERROR_INVALID_PARAMETER);
6188 
6189 	if (lhbaOid.objectType != IMA_OBJECT_TYPE_LHBA)
6190 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6191 
6192 	if (method != IMA_AUTHMETHOD_NONE &&
6193 	    method != IMA_AUTHMETHOD_CHAP &&
6194 	    method != IMA_AUTHMETHOD_SRP &&
6195 	    method != IMA_AUTHMETHOD_KRB5 &&
6196 	    method != IMA_AUTHMETHOD_SPKM1 &&
6197 	    method != IMA_AUTHMETHOD_SPKM2)
6198 		return (IMA_ERROR_INVALID_PARAMETER);
6199 
6200 	os_obtainmutex(libMutex);
6201 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6202 
6203 	for (i = 0; i < number_of_plugins; i++) {
6204 		if (plugintable[i].ownerId == lhbaOid.ownerId) {
6205 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6206 			if (plugintable[i].hPlugin != NULL) {
6207 				os_obtainmutex(plugintable[i].pluginMutex);
6208 #ifdef WIN32
6209 				PassFunc = (IMA_GetInitiatorAuthParmsFn)
6210 				    GetProcAddress(plugintable[i].hPlugin,
6211 				    "IMA_GetInitiatorAuthParms");
6212 #else
6213 				PassFunc = (IMA_GetInitiatorAuthParmsFn)
6214 				    dlsym(plugintable[i].hPlugin,
6215 				    "IMA_GetInitiatorAuthParms");
6216 #endif
6217 
6218 				if (PassFunc != NULL) {
6219 					status = PassFunc(lhbaOid,
6220 					    method, pParms);
6221 				}
6222 				os_releasemutex(plugintable[i].pluginMutex);
6223 			}
6224 
6225 			break;
6226 		}
6227 	}
6228 	os_releasemutex(libMutex);
6229 	return (status);
6230 }
6231 
6232 IMA_API IMA_STATUS IMA_SetInitiatorAuthMethods(
6233     IMA_OID lhbaOid,
6234     IMA_UINT methodCount,
6235     const IMA_AUTHMETHOD *pMethodList) {
6236 	IMA_SetInitiatorAuthMethodsFn PassFunc;
6237 	IMA_UINT i;
6238 	IMA_STATUS status;
6239 
6240 	if (number_of_plugins == -1)
6241 		InitLibrary();
6242 
6243 	if (methodCount == 0 || pMethodList == NULL)
6244 		return (IMA_ERROR_INVALID_PARAMETER);
6245 
6246 	if (lhbaOid.objectType != IMA_OBJECT_TYPE_LHBA)
6247 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6248 
6249 	os_obtainmutex(libMutex);
6250 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6251 
6252 	for (i = 0; i < number_of_plugins; i++) {
6253 		if (plugintable[i].ownerId == lhbaOid.ownerId) {
6254 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6255 			if (plugintable[i].hPlugin != NULL) {
6256 				os_obtainmutex(plugintable[i].pluginMutex);
6257 #ifdef WIN32
6258 				PassFunc = (IMA_SetInitiatorAuthMethodsFn)
6259 				    GetProcAddress(plugintable[i].hPlugin,
6260 				    "IMA_SetInitiatorAuthMethods");
6261 #else
6262 				PassFunc = (IMA_SetInitiatorAuthMethodsFn)
6263 				    dlsym(plugintable[i].hPlugin,
6264 				    "IMA_SetInitiatorAuthMethods");
6265 #endif
6266 
6267 				if (PassFunc != NULL) {
6268 					status = PassFunc(lhbaOid,
6269 					    methodCount, pMethodList);
6270 				}
6271 				os_releasemutex(plugintable[i].pluginMutex);
6272 			}
6273 
6274 			break;
6275 		}
6276 	}
6277 	os_releasemutex(libMutex);
6278 	return (status);
6279 }
6280 
6281 IMA_API IMA_STATUS IMA_SetInitiatorAuthParms(
6282     IMA_OID lhbaOid,
6283     IMA_AUTHMETHOD method,
6284     const IMA_INITIATOR_AUTHPARMS *pParms) {
6285 
6286 	IMA_SetInitiatorAuthParmsFn PassFunc;
6287 	IMA_UINT i;
6288 	IMA_STATUS status;
6289 
6290 	if (number_of_plugins == -1)
6291 		InitLibrary();
6292 
6293 	if (pParms == NULL)
6294 		return (IMA_ERROR_INVALID_PARAMETER);
6295 
6296 	if (method != IMA_AUTHMETHOD_NONE &&
6297 	    method != IMA_AUTHMETHOD_CHAP &&
6298 	    method != IMA_AUTHMETHOD_SRP &&
6299 	    method != IMA_AUTHMETHOD_KRB5 &&
6300 	    method != IMA_AUTHMETHOD_SPKM1 &&
6301 	    method != IMA_AUTHMETHOD_SPKM2)
6302 		return (IMA_ERROR_INVALID_PARAMETER);
6303 
6304 	if (lhbaOid.objectType != IMA_OBJECT_TYPE_LHBA)
6305 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6306 
6307 	os_obtainmutex(libMutex);
6308 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6309 
6310 	for (i = 0; i < number_of_plugins; i++) {
6311 		if (plugintable[i].ownerId == lhbaOid.ownerId) {
6312 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6313 			if (plugintable[i].hPlugin != NULL) {
6314 				os_obtainmutex(plugintable[i].pluginMutex);
6315 #ifdef WIN32
6316 				PassFunc = (IMA_SetInitiatorAuthParmsFn)
6317 				    GetProcAddress(plugintable[i].hPlugin,
6318 				    "IMA_SetInitiatorAuthParms");
6319 #else
6320 				PassFunc = (IMA_SetInitiatorAuthParmsFn)
6321 				    dlsym(plugintable[i].hPlugin,
6322 				    "IMA_SetInitiatorAuthParms");
6323 #endif
6324 
6325 				if (PassFunc != NULL) {
6326 					status =
6327 					    PassFunc(
6328 					    lhbaOid, method, pParms);
6329 				}
6330 				os_releasemutex(plugintable[i].pluginMutex);
6331 			}
6332 
6333 			break;
6334 		}
6335 	}
6336 	os_releasemutex(libMutex);
6337 	return (status);
6338 }
6339 
6340 IMA_API IMA_STATUS IMA_GetStaticDiscoveryTargetOidList(
6341     IMA_OID oid,
6342     IMA_OID_LIST **ppList) {
6343 	IMA_GetStaticDiscoveryTargetOidListFn PassFunc;
6344 	IMA_UINT i;
6345 	IMA_STATUS status;
6346 
6347 	if (number_of_plugins == -1)
6348 		InitLibrary();
6349 
6350 	if (ppList == NULL)
6351 		return (IMA_ERROR_INVALID_PARAMETER);
6352 
6353 	if (oid.objectType != IMA_OBJECT_TYPE_LHBA &&
6354 	    oid.objectType != IMA_OBJECT_TYPE_PNP)
6355 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6356 
6357 	os_obtainmutex(libMutex);
6358 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6359 	for (i = 0; i < number_of_plugins; i++) {
6360 		if (plugintable[i].ownerId == oid.ownerId) {
6361 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6362 			if (plugintable[i].hPlugin != NULL) {
6363 				os_obtainmutex(plugintable[i].pluginMutex);
6364 #ifdef WIN32
6365 				PassFunc =
6366 				    (IMA_GetStaticDiscoveryTargetOidListFn)
6367 				    GetProcAddress(plugintable[i].hPlugin,
6368 				    "IMA_GetStaticDiscoveryTargetOidList");
6369 #else
6370 				PassFunc =
6371 				    (IMA_GetStaticDiscoveryTargetOidListFn)
6372 				    dlsym(plugintable[i].hPlugin,
6373 				    "IMA_GetStaticDiscoveryTargetOidList");
6374 #endif
6375 				if (PassFunc != NULL) {
6376 					status = PassFunc(oid, ppList);
6377 				}
6378 
6379 				os_releasemutex(plugintable[i].pluginMutex);
6380 			}
6381 
6382 			break;
6383 		}
6384 	}
6385 	os_releasemutex(libMutex);
6386 	return (status);
6387 }
6388 
6389 IMA_API IMA_STATUS IMA_GetDiscoveryProperties(
6390     IMA_OID oid,
6391     IMA_DISCOVERY_PROPERTIES *pProps) {
6392 	IMA_GetDiscoveryPropertiesFn PassFunc;
6393 	IMA_UINT i;
6394 	IMA_STATUS status;
6395 
6396 	if (number_of_plugins == -1)
6397 		InitLibrary();
6398 
6399 	if (pProps == NULL)
6400 		return (IMA_ERROR_INVALID_PARAMETER);
6401 
6402 	if (oid.objectType != IMA_OBJECT_TYPE_PHBA &&
6403 	    oid.objectType != IMA_OBJECT_TYPE_LHBA)
6404 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6405 
6406 	os_obtainmutex(libMutex);
6407 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6408 	for (i = 0; i < number_of_plugins; i++) {
6409 		if (plugintable[i].ownerId == oid.ownerId) {
6410 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6411 			if (plugintable[i].hPlugin != NULL) {
6412 				os_obtainmutex(plugintable[i].pluginMutex);
6413 #ifdef WIN32
6414 				PassFunc = (IMA_GetDiscoveryPropertiesFn)
6415 				    GetProcAddress(plugintable[i].hPlugin,
6416 				    "IMA_GetDiscoveryProperties");
6417 #else
6418 				PassFunc = (IMA_GetDiscoveryPropertiesFn)
6419 				    dlsym(plugintable[i].hPlugin,
6420 				    "IMA_GetDiscoveryProperties");
6421 #endif
6422 
6423 				if (PassFunc != NULL) {
6424 					status = PassFunc(oid, pProps);
6425 				}
6426 				os_releasemutex(plugintable[i].pluginMutex);
6427 			}
6428 
6429 			break;
6430 		}
6431 	}
6432 	os_releasemutex(libMutex);
6433 	return (status);
6434 }
6435 
6436 IMA_API IMA_STATUS IMA_AddDiscoveryAddress(
6437     IMA_OID oid,
6438     const IMA_TARGET_ADDRESS discoveryAddress,
6439     IMA_OID *pDiscoveryAddressOid) {
6440 	IMA_AddDiscoveryAddressFn PassFunc;
6441 	IMA_UINT i;
6442 	IMA_STATUS status;
6443 
6444 	if (number_of_plugins == -1)
6445 		InitLibrary();
6446 
6447 	if (oid.objectType != IMA_OBJECT_TYPE_LHBA &&
6448 	    oid.objectType != IMA_OBJECT_TYPE_PNP)
6449 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6450 
6451 	os_obtainmutex(libMutex);
6452 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6453 	for (i = 0; i < number_of_plugins; i++) {
6454 		if (plugintable[i].ownerId == oid.ownerId) {
6455 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6456 			if (plugintable[i].hPlugin != NULL) {
6457 				os_obtainmutex(plugintable[i].pluginMutex);
6458 #ifdef WIN32
6459 				PassFunc = (IMA_AddDiscoveryAddressFn)
6460 				    GetProcAddress(plugintable[i].hPlugin,
6461 				    "IMA_AddDiscoveryAddress");
6462 #else
6463 				PassFunc = (IMA_AddDiscoveryAddressFn)
6464 				    dlsym(plugintable[i].hPlugin,
6465 				    "IMA_AddDiscoveryAddress");
6466 #endif
6467 
6468 				if (PassFunc != NULL) {
6469 					status = PassFunc(oid,
6470 					    discoveryAddress,
6471 					    pDiscoveryAddressOid);
6472 				}
6473 				os_releasemutex(plugintable[i].pluginMutex);
6474 			}
6475 
6476 			break;
6477 		}
6478 	}
6479 	os_releasemutex(libMutex);
6480 	return (status);
6481 }
6482 
6483 IMA_API IMA_STATUS IMA_AddStaticDiscoveryTarget(
6484     IMA_OID oid,
6485     const IMA_STATIC_DISCOVERY_TARGET staticDiscoveryTarget,
6486     IMA_OID *pStaticDiscoveryTargetOid) {
6487 	IMA_AddStaticDiscoveryTargetFn PassFunc;
6488 	IMA_UINT i;
6489 	IMA_STATUS status;
6490 
6491 	if (number_of_plugins == -1)
6492 		InitLibrary();
6493 
6494 	if (oid.objectType != IMA_OBJECT_TYPE_LHBA &&
6495 	    oid.objectType != IMA_OBJECT_TYPE_PNP)
6496 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6497 
6498 	os_obtainmutex(libMutex);
6499 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6500 	for (i = 0; i < number_of_plugins; i++) {
6501 		if (plugintable[i].ownerId == oid.ownerId) {
6502 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6503 			if (plugintable[i].hPlugin != NULL) {
6504 				os_obtainmutex(plugintable[i].pluginMutex);
6505 #ifdef WIN32
6506 				PassFunc = (IMA_AddStaticDiscoveryTargetFn)
6507 				    GetProcAddress(plugintable[i].hPlugin,
6508 				    "IMA_AddStaticDiscoveryTarget");
6509 
6510 #else
6511 				PassFunc = (IMA_AddStaticDiscoveryTargetFn)
6512 				    dlsym(plugintable[i].hPlugin,
6513 				    "IMA_AddStaticDiscoveryTarget");
6514 #endif
6515 
6516 				if (PassFunc != NULL) {
6517 					status = PassFunc(oid,
6518 					    staticDiscoveryTarget,
6519 					    pStaticDiscoveryTargetOid);
6520 				}
6521 				os_releasemutex(plugintable[i].pluginMutex);
6522 			}
6523 
6524 			break;
6525 		}
6526 	}
6527 	os_releasemutex(libMutex);
6528 	return (status);
6529 }
6530 
6531 IMA_API IMA_STATUS IMA_CommitHbaParameters(IMA_OID oid,
6532     IMA_COMMIT_LEVEL commitLevel)
6533 {
6534 	IMA_CommitHbaParametersFn PassFunc;
6535 	IMA_UINT i;
6536 	IMA_STATUS status;
6537 
6538 	if (number_of_plugins == -1)
6539 		InitLibrary();
6540 
6541 	if (oid.objectType != IMA_OBJECT_TYPE_LHBA &&
6542 	    oid.objectType != IMA_OBJECT_TYPE_PHBA)
6543 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6544 
6545 	os_obtainmutex(libMutex);
6546 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6547 	for (i = 0; i < number_of_plugins; i++) {
6548 		if (plugintable[i].ownerId == oid.ownerId) {
6549 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6550 			if (plugintable[i].hPlugin != NULL) {
6551 				os_obtainmutex(plugintable[i].pluginMutex);
6552 #ifdef WIN32
6553 				PassFunc = (IMA_CommitHbaParametersFn)
6554 				    GetProcAddress(plugintable[i].hPlugin,
6555 				    "IMA_CommitHbaParameters");
6556 #else
6557 				PassFunc = (IMA_CommitHbaParametersFn)
6558 				    dlsym(plugintable[i].hPlugin,
6559 				    "IMA_CommitHbaParameters");
6560 #endif
6561 
6562 				if (PassFunc != NULL) {
6563 					status = PassFunc(oid, commitLevel);
6564 				}
6565 				os_releasemutex(plugintable[i].pluginMutex);
6566 			}
6567 
6568 			break;
6569 		}
6570 	}
6571 	os_releasemutex(libMutex);
6572 	return (status);
6573 }
6574 
6575 IMA_API IMA_STATUS IMA_RemoveStaticDiscoveryTarget(
6576     IMA_OID oid) {
6577 	IMA_RemoveStaticDiscoveryTargetFn PassFunc;
6578 	IMA_UINT i;
6579 	IMA_STATUS status;
6580 
6581 	if (number_of_plugins == -1)
6582 		InitLibrary();
6583 
6584 	if (oid.objectType != IMA_OBJECT_TYPE_STATIC_DISCOVERY_TARGET)
6585 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6586 
6587 	os_obtainmutex(libMutex);
6588 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6589 
6590 	for (i = 0; i < number_of_plugins; i++) {
6591 		if (plugintable[i].ownerId == oid.ownerId) {
6592 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6593 			if (plugintable[i].hPlugin != NULL) {
6594 				os_obtainmutex(plugintable[i].pluginMutex);
6595 #ifdef WIN32
6596 				PassFunc = (IMA_RemoveStaticDiscoveryTargetFn)
6597 				    GetProcAddress(plugintable[i].hPlugin,
6598 				    "IMA_RemoveStaticDiscoveryTarget");
6599 #else
6600 				PassFunc = (IMA_RemoveStaticDiscoveryTargetFn)
6601 				    dlsym(plugintable[i].hPlugin,
6602 				    "IMA_RemoveStaticDiscoveryTarget");
6603 #endif
6604 
6605 				if (PassFunc != NULL) {
6606 					status = PassFunc(oid);
6607 				}
6608 				os_releasemutex(plugintable[i].pluginMutex);
6609 			}
6610 
6611 			break;
6612 		}
6613 	}
6614 	os_releasemutex(libMutex);
6615 	return (status);
6616 }
6617 
6618 IMA_API IMA_STATUS IMA_GetStaticDiscoveryTargetProperties(
6619     IMA_OID staticDiscoveryTargetOid,
6620     IMA_STATIC_DISCOVERY_TARGET_PROPERTIES *pProps) {
6621 	IMA_GetStaticDiscoveryTargetPropertiesFn PassFunc;
6622 	IMA_UINT i;
6623 	IMA_STATUS status;
6624 
6625 	if (number_of_plugins == -1)
6626 		InitLibrary();
6627 
6628 	if (pProps == NULL)
6629 		return (IMA_ERROR_INVALID_PARAMETER);
6630 
6631 	if (staticDiscoveryTargetOid.objectType !=
6632 	    IMA_OBJECT_TYPE_STATIC_DISCOVERY_TARGET)
6633 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6634 
6635 	os_obtainmutex(libMutex);
6636 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6637 
6638 	for (i = 0; i < number_of_plugins; i++) {
6639 		if (plugintable[i].ownerId ==
6640 		    staticDiscoveryTargetOid.ownerId) {
6641 
6642 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6643 			if (plugintable[i].hPlugin != NULL) {
6644 				os_obtainmutex(plugintable[i].pluginMutex);
6645 #ifdef WIN32
6646 				PassFunc =
6647 				    (IMA_GetStaticDiscoveryTargetPropertiesFn)
6648 				    GetProcAddress(plugintable[i].hPlugin,
6649 				    "IMA_GetStaticDiscoveryTargetProperties");
6650 #else
6651 				PassFunc =
6652 				    (IMA_GetStaticDiscoveryTargetPropertiesFn)
6653 				    dlsym(plugintable[i].hPlugin,
6654 				    "IMA_GetStaticDiscoveryTargetProperties");
6655 #endif
6656 
6657 				if (PassFunc != NULL) {
6658 					status = PassFunc(
6659 					    staticDiscoveryTargetOid, pProps);
6660 				}
6661 				os_releasemutex(plugintable[i].pluginMutex);
6662 			}
6663 
6664 			break;
6665 		}
6666 	}
6667 	os_releasemutex(libMutex);
6668 	return (status);
6669 }
6670 
6671 IMA_API IMA_STATUS IMA_GetDiscoveryAddressOidList(
6672     IMA_OID Oid,
6673     IMA_OID_LIST **ppList) {
6674 
6675 	IMA_GetDiscoveryAddressOidListFn PassFunc;
6676 	IMA_FreeMemoryFn FreeFunc;
6677 
6678 	IMA_UINT i;
6679 	IMA_UINT j;
6680 	IMA_UINT totalIdCount;
6681 	IMA_STATUS status;
6682 
6683 	if (number_of_plugins == -1)
6684 		InitLibrary();
6685 
6686 	if (ppList == NULL)
6687 		return (IMA_ERROR_INVALID_PARAMETER);
6688 
6689 	if ((Oid.objectType != IMA_OBJECT_TYPE_LHBA) &&
6690 	    (Oid.objectType != IMA_OBJECT_TYPE_PNP)) {
6691 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6692 	}
6693 
6694 	os_obtainmutex(libMutex);
6695 	// Get total id count first
6696 	totalIdCount = 0;
6697 
6698 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6699 	for (i = 0; i < number_of_plugins; i++) {
6700 		if (plugintable[i].ownerId == Oid.ownerId) {
6701 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6702 			if (plugintable[i].hPlugin != NULL) {
6703 				os_obtainmutex(plugintable[i].pluginMutex);
6704 #ifdef WIN32
6705 				PassFunc = (IMA_GetDiscoveryAddressOidListFn)
6706 				    GetProcAddress(plugintable[i].hPlugin,
6707 				    "IMA_GetDiscoveryAddressOidList");
6708 #else
6709 				PassFunc = (IMA_GetDiscoveryAddressOidListFn)
6710 				    dlsym(plugintable[i].hPlugin,
6711 				    "IMA_GetDiscoveryAddressOidList");
6712 #endif
6713 				if (PassFunc != NULL) {
6714 					IMA_OID_LIST *ppOidList;
6715 					status = PassFunc(Oid, &ppOidList);
6716 					if (status == IMA_STATUS_SUCCESS) {
6717 						totalIdCount +=
6718 						    ppOidList->oidCount;
6719 #ifdef WIN32
6720 						FreeFunc = (IMA_FreeMemoryFn)
6721 						    GetProcAddress(
6722 						    plugintable[i].hPlugin,
6723 						    "IMA_FreeMemory");
6724 #else
6725 						FreeFunc = (IMA_FreeMemoryFn)
6726 						    dlsym(
6727 						    plugintable[i].hPlugin,
6728 						    "IMA_FreeMemory");
6729 #endif
6730 						if (FreeFunc != NULL) {
6731 							FreeFunc(ppOidList);
6732 						}
6733 					}
6734 				}
6735 				os_releasemutex(plugintable[i].pluginMutex);
6736 			}
6737 			if (status != IMA_STATUS_SUCCESS) {
6738 				break;
6739 			}
6740 		}
6741 	}
6742 
6743 	*ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST) +
6744 	    (totalIdCount - 1)* sizeof (IMA_OID));
6745 
6746 	if ((*ppList) == NULL) {
6747 		os_releasemutex(libMutex);
6748 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
6749 	}
6750 	(*ppList)->oidCount = totalIdCount;
6751 
6752 	// 2nd pass to copy the id lists
6753 	totalIdCount = 0;
6754 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6755 	for (i = 0; i < number_of_plugins; i++) {
6756 		if (plugintable[i].ownerId == Oid.ownerId) {
6757 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6758 			if (plugintable[i].hPlugin != NULL) {
6759 				os_obtainmutex(plugintable[i].pluginMutex);
6760 #ifdef WIN32
6761 				PassFunc = (IMA_GetDiscoveryAddressOidListFn)
6762 				    GetProcAddress(plugintable[i].hPlugin,
6763 				    "IMA_GetDiscoveryAddressOidList");
6764 #else
6765 				PassFunc = (IMA_GetDiscoveryAddressOidListFn)
6766 				    dlsym(plugintable[i].hPlugin,
6767 				    "IMA_GetDiscoveryAddressOidList");
6768 #endif
6769 				if (PassFunc != NULL) {
6770 					IMA_OID_LIST *ppOidList;
6771 					status = PassFunc(Oid, &ppOidList);
6772 					if (status == IMA_STATUS_SUCCESS) {
6773 						for (j = 0;
6774 						    (j < ppOidList->oidCount) &&
6775 						    (totalIdCount <
6776 						    (*ppList)->oidCount);
6777 						    j++) {
6778 #define	OBJ_SEQ_NUM ppOidList->oids[j].objectSequenceNumber
6779 							(*ppList)->oids
6780 							    [totalIdCount].
6781 							    objectType =
6782 							    ppOidList->oids[j].
6783 							    objectType;
6784 							(*ppList)->oids[
6785 							    totalIdCount].
6786 							    objectSequenceNumber
6787 							    = OBJ_SEQ_NUM;
6788 							(*ppList)->oids[
6789 							    totalIdCount].
6790 							    ownerId =
6791 							    ppOidList->
6792 							    oids[j].ownerId;
6793 							totalIdCount++;
6794 #undef OBJ_SEQ_NUM
6795 						}
6796 #ifdef WIN32
6797 						FreeFunc = (IMA_FreeMemoryFn)
6798 						    GetProcAddress(
6799 						    plugintable[i].hPlugin,
6800 						    "IMA_FreeMemory");
6801 #else
6802 						FreeFunc = (IMA_FreeMemoryFn)
6803 						    dlsym(
6804 						    plugintable[i].hPlugin,
6805 						    "IMA_FreeMemory");
6806 #endif
6807 						if (FreeFunc != NULL) {
6808 							FreeFunc(ppOidList);
6809 						}
6810 					}
6811 				}
6812 				os_releasemutex(plugintable[i].pluginMutex);
6813 			}
6814 			if (status != IMA_STATUS_SUCCESS) {
6815 				free(*ppList);
6816 				break;
6817 			}
6818 		}
6819 	}
6820 
6821 	os_releasemutex(libMutex);
6822 	return (status);
6823 
6824 }
6825 
6826 IMA_API IMA_STATUS IMA_GetSessionOidList(
6827     IMA_OID Oid,
6828     IMA_OID_LIST **ppList) {
6829 
6830 	IMA_GetSessionOidListFn PassFunc;
6831 	IMA_FreeMemoryFn FreeFunc;
6832 
6833 	IMA_UINT i;
6834 	IMA_UINT j;
6835 	IMA_UINT totalIdCount;
6836 	IMA_STATUS status;
6837 
6838 	if (number_of_plugins == -1)
6839 		InitLibrary();
6840 
6841 	if (ppList == NULL)
6842 		return (IMA_ERROR_INVALID_PARAMETER);
6843 
6844 	if ((Oid.objectType != IMA_OBJECT_TYPE_LHBA) &&
6845 	    (Oid.objectType != IMA_OBJECT_TYPE_TARGET)) {
6846 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
6847 	}
6848 
6849 	os_obtainmutex(libMutex);
6850 	// Get total id count first
6851 	totalIdCount = 0;
6852 
6853 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6854 	for (i = 0; i < number_of_plugins; i++) {
6855 		if (plugintable[i].ownerId == Oid.ownerId) {
6856 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6857 			if (plugintable[i].hPlugin != NULL) {
6858 				os_obtainmutex(plugintable[i].pluginMutex);
6859 #ifdef WIN32
6860 				PassFunc = (IMA_GetSessionOidListFn)
6861 				    GetProcAddress(plugintable[i].hPlugin,
6862 				    "IMA_GetSessionOidList");
6863 #else
6864 				PassFunc = (IMA_GetSessionOidListFn)
6865 				    dlsym(plugintable[i].hPlugin,
6866 				    "IMA_GetSessionOidList");
6867 #endif
6868 				if (PassFunc != NULL) {
6869 					IMA_OID_LIST *ppOidList;
6870 					status = PassFunc(Oid, &ppOidList);
6871 					if (status == IMA_STATUS_SUCCESS) {
6872 						totalIdCount +=
6873 						    ppOidList->oidCount;
6874 #ifdef WIN32
6875 						FreeFunc = (IMA_FreeMemoryFn)
6876 						    GetProcAddress(
6877 						    plugintable[i].hPlugin,
6878 						    "IMA_FreeMemory");
6879 #else
6880 						FreeFunc = (IMA_FreeMemoryFn)
6881 						    dlsym(
6882 						    plugintable[i].hPlugin,
6883 						    "IMA_FreeMemory");
6884 #endif
6885 						if (FreeFunc != NULL) {
6886 							FreeFunc(ppOidList);
6887 						}
6888 					}
6889 
6890 				}
6891 				os_releasemutex(plugintable[i].pluginMutex);
6892 			}
6893 			if (status != IMA_STATUS_SUCCESS) {
6894 				break;
6895 			}
6896 		}
6897 	}
6898 
6899 	*ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST) +
6900 	    (totalIdCount - 1)* sizeof (IMA_OID));
6901 
6902 	if ((*ppList) == NULL) {
6903 		os_releasemutex(libMutex);
6904 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
6905 	}
6906 	(*ppList)->oidCount = totalIdCount;
6907 
6908 	// 2nd pass to copy the id lists
6909 	totalIdCount = 0;
6910 	status = IMA_ERROR_OBJECT_NOT_FOUND;
6911 	for (i = 0; i < number_of_plugins; i++) {
6912 		if (plugintable[i].ownerId == Oid.ownerId) {
6913 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
6914 			if (plugintable[i].hPlugin != NULL) {
6915 				os_obtainmutex(plugintable[i].pluginMutex);
6916 #ifdef WIN32
6917 				PassFunc = (IMA_GetSessionOidListFn)
6918 				    GetProcAddress(plugintable[i].hPlugin,
6919 				    "IMA_GetSessionOidList");
6920 #else
6921 				PassFunc = (IMA_GetSessionOidListFn)
6922 				    dlsym(plugintable[i].hPlugin,
6923 				    "IMA_GetSessionOidList");
6924 #endif
6925 				if (PassFunc != NULL) {
6926 					IMA_OID_LIST *ppOidList;
6927 					status = PassFunc(Oid, &ppOidList);
6928 					if (status == IMA_STATUS_SUCCESS) {
6929 						for (j = 0;
6930 						    (j < ppOidList->oidCount) &&
6931 						    (totalIdCount <
6932 						    (*ppList)->oidCount);
6933 						    j++) {
6934 
6935 #define	OBJ_SEQ_NUM ppOidList->oids[j].objectSequenceNumber
6936 							(*ppList)->oids[
6937 							    totalIdCount].
6938 							    objectType =
6939 							    ppOidList->oids[j].
6940 							    objectType;
6941 							(*ppList)->oids[
6942 							    totalIdCount].
6943 							    objectSequenceNumber
6944 							    = OBJ_SEQ_NUM;
6945 							(*ppList)->oids[
6946 							    totalIdCount].
6947 							    ownerId =
6948 							    ppOidList->oids[j].
6949 							    ownerId;
6950 							totalIdCount++;
6951 #undef OBJ_SEQ_NUM
6952 						}
6953 #ifdef WIN32
6954 						FreeFunc = (IMA_FreeMemoryFn)
6955 						    GetProcAddress(
6956 						    plugintable[i].hPlugin,
6957 						    "IMA_FreeMemory");
6958 #else
6959 						FreeFunc = (IMA_FreeMemoryFn)
6960 						    dlsym(
6961 						    plugintable[i].hPlugin,
6962 						    "IMA_FreeMemory");
6963 #endif
6964 						if (FreeFunc != NULL) {
6965 							FreeFunc(ppOidList);
6966 						}
6967 					}
6968 				}
6969 				os_releasemutex(plugintable[i].pluginMutex);
6970 			}
6971 			if (status != IMA_STATUS_SUCCESS) {
6972 				free(*ppList);
6973 				break;
6974 			}
6975 		}
6976 	}
6977 
6978 	os_releasemutex(libMutex);
6979 	return (status);
6980 
6981 }
6982 
6983 IMA_API IMA_STATUS IMA_GetConnectionOidList(
6984     IMA_OID Oid,
6985     IMA_OID_LIST **ppList) {
6986 
6987 	IMA_GetSessionOidListFn PassFunc;
6988 	IMA_FreeMemoryFn FreeFunc;
6989 
6990 	IMA_UINT i;
6991 	IMA_UINT j;
6992 	IMA_UINT totalIdCount;
6993 	IMA_STATUS status;
6994 
6995 	if (number_of_plugins == -1)
6996 		InitLibrary();
6997 
6998 	if (ppList == NULL)
6999 		return (IMA_ERROR_INVALID_PARAMETER);
7000 
7001 	if (Oid.objectType != IMA_OBJECT_TYPE_SESSION) {
7002 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
7003 	}
7004 
7005 	os_obtainmutex(libMutex);
7006 	// Get total id count first
7007 	totalIdCount = 0;
7008 
7009 	status = IMA_ERROR_OBJECT_NOT_FOUND;
7010 	for (i = 0; i < number_of_plugins; i++) {
7011 		if (plugintable[i].ownerId == Oid.ownerId) {
7012 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
7013 			if (plugintable[i].hPlugin != NULL) {
7014 				os_obtainmutex(plugintable[i].pluginMutex);
7015 #ifdef WIN32
7016 				PassFunc = (IMA_GetConnectionOidListFn)
7017 				    GetProcAddress(plugintable[i].hPlugin,
7018 				    "IMA_GetConnectionOidList");
7019 #else
7020 				PassFunc = (IMA_GetConnectionOidListFn)
7021 				    dlsym(plugintable[i].hPlugin,
7022 				    "IMA_GetConnectionOidList");
7023 #endif
7024 				if (PassFunc != NULL) {
7025 					IMA_OID_LIST *ppOidList;
7026 					status = PassFunc(Oid, &ppOidList);
7027 					if (status == IMA_STATUS_SUCCESS) {
7028 						totalIdCount +=
7029 						    ppOidList->oidCount;
7030 #ifdef WIN32
7031 						FreeFunc = (IMA_FreeMemoryFn)
7032 						    GetProcAddress(
7033 						    plugintable[i].hPlugin,
7034 						    "IMA_FreeMemory");
7035 #else
7036 						FreeFunc = (IMA_FreeMemoryFn)
7037 						    dlsym(
7038 						    plugintable[i].hPlugin,
7039 						    "IMA_FreeMemory");
7040 #endif
7041 						if (FreeFunc != NULL) {
7042 							FreeFunc(ppOidList);
7043 						}
7044 					}
7045 
7046 				}
7047 				os_releasemutex(plugintable[i].pluginMutex);
7048 			}
7049 			if (status != IMA_STATUS_SUCCESS) {
7050 				break;
7051 			}
7052 		}
7053 	}
7054 
7055 
7056 	*ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST)
7057 	    + (totalIdCount - 1)* sizeof (IMA_OID));
7058 
7059 	if ((*ppList) == NULL) {
7060 		os_releasemutex(libMutex);
7061 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
7062 	}
7063 	(*ppList)->oidCount = totalIdCount;
7064 
7065 	// 2nd pass to copy the id lists
7066 	totalIdCount = 0;
7067 	status = IMA_ERROR_OBJECT_NOT_FOUND;
7068 	for (i = 0; i < number_of_plugins; i++) {
7069 		if (plugintable[i].ownerId == Oid.ownerId) {
7070 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
7071 			if (plugintable[i].hPlugin != NULL) {
7072 				os_obtainmutex(plugintable[i].pluginMutex);
7073 #ifdef WIN32
7074 				PassFunc = (IMA_GetConnectionOidListFn)
7075 				    GetProcAddress(plugintable[i].hPlugin,
7076 				    "IMA_GetConnectionOidList");
7077 #else
7078 				PassFunc = (IMA_GetConnectionOidListFn)
7079 				    dlsym(plugintable[i].hPlugin,
7080 				    "IMA_GetConnectionOidList");
7081 #endif
7082 				if (PassFunc != NULL) {
7083 					IMA_OID_LIST *ppOidList;
7084 					status = PassFunc(Oid, &ppOidList);
7085 					if (status == IMA_STATUS_SUCCESS) {
7086 						for (j = 0; (
7087 						    j < ppOidList->oidCount) &&
7088 						    (totalIdCount <
7089 						    (*ppList)->oidCount);
7090 						    j++) {
7091 #define	OBJ_SEQ_NUM ppOidList->oids[j].objectSequenceNumber
7092 							(*ppList)->
7093 							    oids[totalIdCount].
7094 							    objectType =
7095 							    ppOidList->
7096 							    oids[j].objectType;
7097 							(*ppList)->
7098 							    oids[totalIdCount].
7099 							    objectSequenceNumber
7100 							    = OBJ_SEQ_NUM;
7101 							(*ppList)->
7102 							    oids[totalIdCount].
7103 							    ownerId =
7104 							    ppOidList->oids[j].
7105 							    ownerId;
7106 							totalIdCount++;
7107 #undef OBJ_SEQ_NUM
7108 						}
7109 #ifdef WIN32
7110 						FreeFunc = (IMA_FreeMemoryFn)
7111 						    GetProcAddress(
7112 						    plugintable[i].hPlugin,
7113 						    "IMA_FreeMemory");
7114 #else
7115 						FreeFunc = (IMA_FreeMemoryFn)
7116 						    dlsym(
7117 						    plugintable[i].hPlugin,
7118 						    "IMA_FreeMemory");
7119 #endif
7120 						if (FreeFunc != NULL) {
7121 							FreeFunc(ppOidList);
7122 						}
7123 					}
7124 				}
7125 				os_releasemutex(plugintable[i].pluginMutex);
7126 			}
7127 			if (status != IMA_STATUS_SUCCESS) {
7128 				free(*ppList);
7129 				break;
7130 			}
7131 		}
7132 	}
7133 	os_releasemutex(libMutex);
7134 	return (status);
7135 
7136 }
7137 
7138 IMA_API IMA_STATUS IMA_RemoveDiscoveryAddress(
7139     IMA_OID discoveryAddressOid) {
7140 
7141 	IMA_RemoveDiscoveryAddressFn PassFunc;
7142 	IMA_UINT i;
7143 	IMA_STATUS status;
7144 
7145 	if (number_of_plugins == -1)
7146 		InitLibrary();
7147 
7148 	if (discoveryAddressOid.objectType !=
7149 	    IMA_OBJECT_TYPE_DISCOVERY_ADDRESS) {
7150 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
7151 	}
7152 
7153 	os_obtainmutex(libMutex);
7154 	status = IMA_ERROR_OBJECT_NOT_FOUND;
7155 
7156 	for (i = 0; i < number_of_plugins; i++) {
7157 		if (plugintable[i].ownerId == discoveryAddressOid.ownerId) {
7158 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
7159 			if (plugintable[i].hPlugin != NULL) {
7160 				os_obtainmutex(plugintable[i].pluginMutex);
7161 #ifdef WIN32
7162 				PassFunc = (IMA_RemoveDiscoveryAddressFn)
7163 				    GetProcAddress(plugintable[i].hPlugin,
7164 				    "IMA_RemoveDiscoveryAddress");
7165 #else
7166 				PassFunc = (IMA_RemoveDiscoveryAddressFn)
7167 				    dlsym(plugintable[i].hPlugin,
7168 				    "IMA_RemoveDiscoveryAddress");
7169 #endif
7170 
7171 				if (PassFunc != NULL) {
7172 					status = PassFunc(discoveryAddressOid);
7173 				}
7174 				os_releasemutex(plugintable[i].pluginMutex);
7175 			}
7176 
7177 			break;
7178 		}
7179 	}
7180 	os_releasemutex(libMutex);
7181 	return (status);
7182 }
7183 
7184 IMA_API IMA_STATUS IMA_GetIpsecProperties(
7185     IMA_OID oid,
7186     IMA_IPSEC_PROPERTIES *pProps) {
7187 	IMA_GetIpsecPropertiesFn PassFunc;
7188 	IMA_UINT i;
7189 	IMA_STATUS status;
7190 
7191 	if (number_of_plugins == -1)
7192 		InitLibrary();
7193 
7194 	if (pProps == NULL)
7195 		return (IMA_ERROR_INVALID_PARAMETER);
7196 
7197 	if (oid.objectType != IMA_OBJECT_TYPE_PNP &&
7198 	    oid.objectType != IMA_OBJECT_TYPE_LHBA) {
7199 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
7200 	}
7201 
7202 	os_obtainmutex(libMutex);
7203 	status = IMA_ERROR_OBJECT_NOT_FOUND;
7204 
7205 	for (i = 0; i < number_of_plugins; i++) {
7206 		if (plugintable[i].ownerId == oid.ownerId) {
7207 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
7208 			if (plugintable[i].hPlugin != NULL) {
7209 				os_obtainmutex(plugintable[i].pluginMutex);
7210 #ifdef WIN32
7211 				PassFunc = (IMA_GetIpsecPropertiesFn)
7212 				    GetProcAddress(plugintable[i].hPlugin,
7213 				    "IMA_GetIpsecProperties");
7214 #else
7215 				PassFunc = (IMA_GetIpsecPropertiesFn)
7216 				    dlsym(plugintable[i].hPlugin,
7217 				    "IMA_GetIpsecProperties");
7218 #endif
7219 
7220 				if (PassFunc != NULL) {
7221 					status = PassFunc(oid, pProps);
7222 				}
7223 				os_releasemutex(plugintable[i].pluginMutex);
7224 			}
7225 
7226 			break;
7227 		}
7228 	}
7229 	os_releasemutex(libMutex);
7230 	return (status);
7231 }
7232 
7233 IMA_API IMA_STATUS IMA_GetAddressKeys(
7234     IMA_OID targetOid,
7235     IMA_ADDRESS_KEYS **ppKeys) {
7236 	IMA_GetAddressKeysFn PassFunc;
7237 	IMA_FreeMemoryFn FreeFunc;
7238 
7239 	IMA_STATUS status;
7240 	IMA_UINT i;
7241 
7242 
7243 	if (number_of_plugins == -1)
7244 		InitLibrary();
7245 
7246 	if (ppKeys == NULL)
7247 		return (IMA_ERROR_INVALID_PARAMETER);
7248 
7249 	if (targetOid.objectType != IMA_OBJECT_TYPE_TARGET)
7250 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
7251 
7252 	os_obtainmutex(libMutex);
7253 
7254 	status = IMA_ERROR_OBJECT_NOT_FOUND;
7255 	for (i = 0; i < number_of_plugins; i++) {
7256 
7257 		if (plugintable[i].ownerId == targetOid.ownerId) {
7258 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
7259 			if (plugintable[i].hPlugin != NULL) {
7260 				os_obtainmutex(plugintable[i].pluginMutex);
7261 #ifdef WIN32
7262 				PassFunc =
7263 				    (IMA_GetAddressKeysFn) GetProcAddress(
7264 				    plugintable[i].hPlugin,
7265 				    "IMA_GetAddressKeys");
7266 #else
7267 				PassFunc = (IMA_GetAddressKeysFn) dlsym(
7268 				    plugintable[i].hPlugin,
7269 				    "IMA_GetAddressKeys");
7270 #endif
7271 
7272 				if (PassFunc != NULL) {
7273 					IMA_ADDRESS_KEYS *ppKeysList;
7274 					IMA_UINT addrSize;
7275 					addrSize = sizeof (IMA_ADDRESS_KEYS);
7276 					status =
7277 					    PassFunc(targetOid, &ppKeysList);
7278 					if (IMA_SUCCESS(status)) {
7279 
7280 						*ppKeys =
7281 						    (IMA_ADDRESS_KEYS*)calloc(1,
7282 						    addrSize +
7283 						    (ppKeysList->addressKeyCount
7284 						    - 1) * addrSize);
7285 						if ((*ppKeys) == NULL) {
7286 							status = EUOS_ERROR;
7287 						} else {
7288 							memcpy((*ppKeys),
7289 							    ppKeysList,
7290 							    addrSize +
7291 							    (ppKeysList->
7292 							    addressKeyCount-1)*
7293 							    addrSize);
7294 
7295 						}
7296 #ifdef WIN32
7297 						FreeFunc = (IMA_FreeMemoryFn)
7298 						    GetProcAddress(
7299 						    plugintable[i].hPlugin,
7300 						    "IMA_FreeMemory");
7301 #else
7302 						FreeFunc = (IMA_FreeMemoryFn)
7303 						    dlsym(
7304 						    plugintable[i].hPlugin,
7305 						    "IMA_FreeMemory");
7306 #endif
7307 						if (FreeFunc != NULL) {
7308 							FreeFunc(ppKeysList);
7309 						}
7310 					}
7311 				}
7312 				os_releasemutex(plugintable[i].pluginMutex);
7313 			}
7314 
7315 			break;
7316 		}
7317 	}
7318 	os_releasemutex(libMutex);
7319 	return (status);
7320 }
7321 
7322 IMA_API IMA_STATUS IMA_GetDiscoveryAddressProperties(
7323     IMA_OID oid,
7324     IMA_DISCOVERY_ADDRESS_PROPERTIES *pProps) {
7325 
7326 	IMA_GetDiscoveryAddressPropertiesFn PassFunc;
7327 	IMA_UINT i;
7328 	IMA_STATUS status;
7329 
7330 	if (number_of_plugins == -1)
7331 		InitLibrary();
7332 
7333 	if (pProps == NULL)
7334 		return (IMA_ERROR_INVALID_PARAMETER);
7335 
7336 	if (oid.objectType != IMA_OBJECT_TYPE_DISCOVERY_ADDRESS)
7337 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
7338 
7339 	os_obtainmutex(libMutex);
7340 	status = IMA_ERROR_OBJECT_NOT_FOUND;
7341 
7342 	for (i = 0; i < number_of_plugins; i++) {
7343 		if (plugintable[i].ownerId == oid.ownerId) {
7344 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
7345 			if (plugintable[i].hPlugin != NULL) {
7346 				os_obtainmutex(plugintable[i].pluginMutex);
7347 #ifdef WIN32
7348 				PassFunc =
7349 				    (IMA_GetDiscoveryAddressPropertiesFn)
7350 				    GetProcAddress(
7351 				    plugintable[i].hPlugin,
7352 				    "IMA_GetDiscoveryAddressProperties");
7353 #else
7354 				PassFunc =
7355 				    (IMA_GetDiscoveryAddressPropertiesFn) dlsym(
7356 				    plugintable[i].hPlugin,
7357 				    "IMA_GetDiscoveryAddressProperties");
7358 #endif
7359 
7360 				if (PassFunc != NULL) {
7361 					status = PassFunc(oid, pProps);
7362 				}
7363 				os_releasemutex(plugintable[i].pluginMutex);
7364 			}
7365 
7366 			break;
7367 		}
7368 	}
7369 	os_releasemutex(libMutex);
7370 	return (status);
7371 }
7372 
7373 IMA_API IMA_STATUS QIMA_SetUpdateInterval(
7374     IMA_OID pluginOid, time_t interval) {
7375 	QIMA_SetUpdateIntervalFn updFunc;
7376 	IMA_UINT i;
7377 	IMA_STATUS status;
7378 
7379 	if (number_of_plugins == -1)
7380 		InitLibrary();
7381 
7382 	if (interval <= 1)
7383 		return (IMA_ERROR_INVALID_PARAMETER);
7384 
7385 	if ((pluginOid.objectType != IMA_OBJECT_TYPE_PLUGIN) ||
7386 	    (pluginOid.objectSequenceNumber != 0))
7387 		return (IMA_ERROR_INVALID_PARAMETER);
7388 
7389 	os_obtainmutex(libMutex);
7390 	status = IMA_ERROR_OBJECT_NOT_FOUND;
7391 
7392 	for (i = 0; i < number_of_plugins; i++) {
7393 		if (plugintable[i].ownerId == pluginOid.ownerId) {
7394 			status = IMA_ERROR_UNEXPECTED_OS_ERROR;
7395 			if (plugintable[i].hPlugin != NULL) {
7396 				os_obtainmutex(plugintable[i].pluginMutex);
7397 #ifdef WIN32
7398 				updFunc = (QIMA_SetUpdateIntervalFn)
7399 				    GetProcAddress(
7400 				    plugintable[i].hPlugin,
7401 				    "QIMA_SetUpdateInterval");
7402 #else
7403 				updFunc = (QIMA_SetUpdateIntervalFn) dlsym(
7404 				    plugintable[i].hPlugin,
7405 				    "QIMA_SetUpdateInterval");
7406 #endif
7407 
7408 				if (updFunc != NULL) {
7409 					status = updFunc(pluginOid, interval);
7410 				}
7411 				os_releasemutex(plugintable[i].pluginMutex);
7412 			}
7413 
7414 			break;
7415 		}
7416 	}
7417 	os_releasemutex(libMutex);
7418 	return (status);
7419 
7420 }
7421