(unsigned char)hasRootCerts, (unsigned char)hasRootTrust);
hasRootCerts, hasRootTrust);
secmod_DecodeData(char *defParams, DBT *data, PRBool *retInternal){    secmodData *encoded;    secmodSlotData *slots;    char *commonName = NULL,*dllName = NULL,*parameters = NULL;    unsigned char *names;    unsigned short len;    unsigned long slotCount;    unsigned short offset;    PRBool isOldVersion  = PR_FALSE;    PRBool internal, isFIPS, isModuleDB=PR_FALSE, isModuleDBOnly=PR_FALSE;    PRBool extended=PR_FALSE;    PRBool hasRootCerts=PR_FALSE,hasRootTrust=PR_FALSE;    unsigned long trustOrder=PK11_DEFAULT_TRUST_ORDER, 				cipherOrder=PK11_DEFAULT_CIPHER_ORDER;    unsigned long ssl0=0, ssl1=0;    char **slotStrings = NULL;    unsigned long slotID,defaultFlags,timeout;    char *nss,*moduleSpec;    int i;    PLArenaPool *arena;    arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);    if (arena == NULL) return NULL;    encoded = (secmodData *)data->data;    names = (unsigned char *)data->data;    offset = SECMOD_GETSHORT(encoded->slotOffset);    slots = (secmodSlotData *) (names + offset + 2);    slotCount = SECMOD_GETSHORT(names + offset);    names += SECMOD_GETSHORT(encoded->nameStart);    * retInternal = internal = (encoded->internal != 0) ? PR_TRUE: PR_FALSE;    isFIPS = (encoded->fips != 0) ? PR_TRUE: PR_FALSE;    len = SECMOD_GETSHORT(names);    if (internal && (encoded->major == SECMOD_DB_NOUI_VERSION_MAJOR) && 	(encoded->minor <= SECMOD_DB_NOUI_VERSION_MINOR)) {	isOldVersion = PR_TRUE;    }    if ((encoded->major == SECMOD_DB_EXT1_VERSION_MAJOR) &&	(encoded->minor >= SECMOD_DB_EXT1_VERSION_MINOR)) {	trustOrder = SECMOD_GETLONG(encoded->trustOrder);	cipherOrder = SECMOD_GETLONG(encoded->cipherOrder);	isModuleDB = (encoded->isModuleDB != 0) ? PR_TRUE: PR_FALSE;	isModuleDBOnly = (encoded->isModuleDBOnly != 0) ? PR_TRUE: PR_FALSE;	extended = PR_TRUE;    }     if (internal && !extended) {	trustOrder = 0;	cipherOrder = 100;    }    /* decode the common name */    commonName = (char*)PORT_ArenaAlloc(arena,len+1);    if (commonName == NULL) {	PORT_FreeArena(arena,PR_TRUE);	return NULL;    }    PORT_Memcpy(commonName,&names[2],len);    commonName[len] = 0;    /* decode the DLL name */    names += len+2;    len = SECMOD_GETSHORT(names);    if (len) {	dllName = (char*)PORT_ArenaAlloc(arena,len + 1);	if (dllName == NULL) {	    PORT_FreeArena(arena,PR_TRUE);	    return NULL;	}	PORT_Memcpy(dllName,&names[2],len);	dllName[len] = 0;    }    if (!internal && extended) {	names += len+2;	len = SECMOD_GETSHORT(names);	if (len) {	    parameters = (char*)PORT_ArenaAlloc(arena,len + 1);	    if (parameters == NULL) {		PORT_FreeArena(arena,PR_TRUE);		return NULL;	    }	    PORT_Memcpy(parameters,&names[2],len);	    parameters[len] = 0;	}    }    if (internal) {	parameters = PORT_ArenaStrdup(arena,defParams);    }    /* decode SSL cipher enable flags */    ssl0 = SECMOD_GETLONG(encoded->ssl);    ssl1 = SECMOD_GETLONG(&encoded->ssl[4]);    /*  slotCount; */    slotStrings = (char **)PORT_ArenaAlloc(arena, slotCount * sizeof(char *));    for (i=0; i < (int) slotCount; i++) {	slotID = SECMOD_GETLONG(slots[i].slotID);	defaultFlags = SECMOD_GETLONG(slots[i].defaultFlags);	if (isOldVersion && internal && (slotID != 2)) {		unsigned long internalFlags=			pk11_argSlotFlags("slotFlags",SECMOD_SLOT_FLAGS);		defaultFlags |= internalFlags;	}	timeout = SECMOD_GETLONG(slots[i].timeout);	hasRootCerts = slots[i].hasRootCerts;	if (hasRootCerts && !extended) {	    trustOrder = 100;	}	slotStrings[i] = pk11_mkSlotString(slotID, defaultFlags, timeout, 	                                   (unsigned char)slots[i].askpw, 	                                   (unsigned char)hasRootCerts, 	                                   (unsigned char)hasRootTrust);    }    nss = pk11_mkNSS(slotStrings, slotCount, internal, isFIPS, isModuleDB, 	isModuleDBOnly, internal, trustOrder, cipherOrder, ssl0, ssl1);    moduleSpec = pk11_mkNewModuleSpec(dllName,commonName,parameters,nss);    PR_smprintf_free(nss);    PORT_FreeArena(arena,PR_TRUE);    return (moduleSpec);}