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