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