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