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