static PGPError fileClose (PGPFile *file) { File *fp = (File *)file->priv; PGPError code = kPGPError_NoErr; pgpAssertAddrValid( file, PGPFile ); if ((fp->flags & FLAGS_FILE) && !(fp->flags & FLAGS_DONTCLOSE)) code = (PGPError)fclose (fp->f); else if (fp->flags & FLAGS_PROC) { if (fp->doClose) code = (PGPError)fp->doClose (fp->f, fp->closeArg); /* We may not be able to 'close' here.. I hope that is ok */ } if (code) { code = kPGPError_FileOpFailed; setError (file, (PGPError)code); fp->error = (PGPError)code; return code; } if (fp->cfb) PGPFreeCFBContext(fp->cfb); pgpClearMemory( fp, sizeof (*fp)); PGPFreeData( fp); pgpClearMemory( file, sizeof (*file)); PGPFreeData( file); return code; }
LPSTR __cdecl _pgp_decrypt_key(LPCSTR szEncMsg, LPCSTR pgpKey) { #if defined(_WIN64) return 0; #else LPSTR szPlainMsg = 0; PGPSize dwPlainMsgLen; PGPUInt32 dwKeys; PGPKeyDBRef PrivateKeyDB; if (CheckPGPError(_pgp_import_key(&PrivateKeyDB,pgpKey))) return 0; PGPCountKeysInKeyDB(PrivateKeyDB, &dwKeys); if(dwKeys==0) { PGPFreeKeyDB(PrivateKeyDB); return 0; } int iTry = 0; do { if (!pszPassphrase && PGPPassphraseDialog(pgpContext, PGPOUIOutputPassphrase(pgpContext, &pszPassphrase), PGPOLastOption(pgpContext)) == kPGPError_UserAbort) { iTry = 3; break; } PGPError err = PGPDecode(pgpContext, PGPOInputBuffer(pgpContext, szEncMsg, lstrlen(szEncMsg)), PGPOAllocatedOutputBuffer(pgpContext, (LPVOID *)&szPlainMsg, 16384, &dwPlainMsgLen), PGPOKeyDBRef(pgpContext, PrivateKeyDB), PGPOPassphrase(pgpContext, pszPassphrase), PGPOLastOption(pgpContext)); if (CheckPGPError(err)) iTry = 3; else if (!dwPlainMsgLen) { PGPFreeData(pszPassphrase); pszPassphrase = 0; iTry++; } } while(!dwPlainMsgLen && iTry<3); PGPFreeKeyDB(PrivateKeyDB); if(iTry == 3) return 0; LPSTR szMsg = (LPSTR) LocalAlloc(LPTR,dwPlainMsgLen+1); _pgp_memcpy(szMsg, szPlainMsg, dwPlainMsgLen); szMsg[dwPlainMsgLen] = 0; PGPFreeData((LPVOID)szPlainMsg); return szMsg; #endif }
static void sTestMultiAllocations( PGPMemoryMgrRef mgr) { #define kNumTestPtrs 50 void * plain[ kNumTestPtrs ]; void * secure[ kNumTestPtrs ]; PGPUInt32 idx; void * temp; PGPError err = kPGPError_NoErr; for( idx = 0; idx < kNumTestPtrs; ++idx ) { PGPSize ptrSize; PGPFlags flags; ptrSize = idx * 17; plain[ idx ] = PGPNewData( mgr, ptrSize, 0); if ( NULL!=(int)( plain[ idx ] ) ) { flags = PGPGetMemoryMgrDataInfo( plain[ idx ] ); pgpAssert( ( flags & kPGPMemoryMgrBlockInfo_Valid ) != 0 ); pgpAssert( ( flags & kPGPMemoryMgrBlockInfo_Secure ) == 0 ); pgpAssert( ( flags & kPGPMemoryMgrBlockInfo_NonPageable ) == 0 ); } secure[ idx ] = PGPNewSecureData( mgr, ptrSize, 0 ); if ( NULL!=(int)( secure[ idx ] ) ) { flags = PGPGetMemoryMgrDataInfo( secure[ idx ] ); pgpAssert( ( flags & kPGPMemoryMgrBlockInfo_Valid ) != 0 ); pgpAssert( ( flags & kPGPMemoryMgrBlockInfo_Secure ) != 0 ); } } /* free even numbered items */ for( idx = 0; idx < kNumTestPtrs; idx += 2 ) { PGPFreeData( plain[ idx ] ); PGPFreeData( secure[ idx ] ); } /* free odd numbered items */ for( idx = 1; idx < kNumTestPtrs; idx += 2 ) { PGPFreeData( plain[ idx ] ); PGPFreeData( secure[ idx ] ); } /* test realloc case with NULL ptr */ temp = NULL; err = PGPReallocData( mgr, &temp, 1000, 0 ); pgpAssertNoErr( err ); pgpAssert( NULL!=(int)( temp ) ); PGPFreeData( temp ); }
LPSTR __cdecl _pgp_decrypt_keydb(LPCSTR szEncMsg) { LPSTR szPlainMsg = 0; DWORD dwPlainMsgLen; ClearPGPError(); if(!pgpKeyDB) return 0; int iTry = 0; do { if (!pszPassphrase && PGPPassphraseDialog(pgpContext, PGPOUIOutputPassphrase(pgpContext, &pszPassphrase), PGPOLastOption(pgpContext)) == kPGPError_UserAbort) { iTry = 3; break; } PGPError err = PGPDecode(pgpContext, PGPOInputBuffer(pgpContext, szEncMsg, lstrlen(szEncMsg)), PGPOAllocatedOutputBuffer(pgpContext, (LPVOID *)&szPlainMsg, 16384, (PGPUInt32 *)&dwPlainMsgLen), #if (PGP_WIN32 < 0x700) PGPOKeySetRef(pgpContext, pgpKeyDB), #else PGPOKeyDBRef(pgpContext, pgpKeyDB), #endif PGPOPassphrase(pgpContext, pszPassphrase), PGPOLastOption(pgpContext)); if (CheckPGPError(err)) iTry = 3; else if (!dwPlainMsgLen) { PGPFreeData(pszPassphrase); pszPassphrase = 0; iTry++; } } while(!dwPlainMsgLen && iTry<3); if(iTry == 3) return 0; LPSTR szMsg = (LPSTR) LocalAlloc(LPTR,dwPlainMsgLen+1); _pgp_memcpy(szMsg, szPlainMsg, dwPlainMsgLen); szMsg[dwPlainMsgLen] = 0; PGPFreeData((LPVOID)szPlainMsg); return szMsg; }
VOID KMFreePhrase (LPSTR pszPhrase) { if (pszPhrase) { PGPFreeData (pszPhrase); } }
static void sFreeDefaultMemoryMgrList(PGPDefaultMemoryMgrRef defaultRef) { if( NULL!=(int)( defaultRef->memoryMgrList ) ) { MemoryMgrInfo *cur; PGPRMWOLockStartWriting( &(defaultRef->memoryMgrListLock) ); cur = defaultRef->memoryMgrList; while( NULL!=(int)( cur ) ) { MemoryMgrInfo *next; PGPMemoryMgrRef mgr; next = cur->next; mgr = cur->mgr; PGPFreeData( cur ); PGPFreeMemoryMgr( mgr ); cur = next; } defaultRef->memoryMgrList = NULL; PGPRMWOLockStopWriting( &(defaultRef->memoryMgrListLock) ); DeletePGPRMWOLock( &(defaultRef->memoryMgrListLock) ); } }
LPSTR __cdecl _pgp_encrypt_keydb(LPCSTR szPlainMsg, PVOID pgpKeyID) { #if defined(_WIN64) return 0; #else PGPKeyID *RemoteKeyID = (PGPKeyID *) pgpKeyID; LPSTR szEncMsg = 0; PGPSize dwEncMsgLen; ClearPGPError(); if (!pgpKeyDB) return 0; PGPKeyDBObjRef PublicKey; PGPFindKeyByKeyID(pgpKeyDB, RemoteKeyID, &PublicKey); PGPError err = PGPEncode(pgpContext, PGPOInputBuffer(pgpContext, szPlainMsg, lstrlen(szPlainMsg)), PGPOArmorOutput(pgpContext, TRUE), PGPOAllocatedOutputBuffer(pgpContext, (LPVOID *)&szEncMsg, 16384, &dwEncMsgLen), PGPOEncryptToKeyDBObj(pgpContext, PublicKey), PGPOVersionString(pgpContext, szVersionStr), PGPOLastOption(pgpContext)); if (CheckPGPError(err)) return 0; LPSTR szMsg = (LPSTR) LocalAlloc(LPTR,dwEncMsgLen+1); _pgp_memcpy(szMsg, szEncMsg, dwEncMsgLen); szMsg[dwEncMsgLen] = 0; PGPFreeData((LPVOID)szEncMsg); return szMsg; #endif }
/* Initialize BSafe pubkey structure from a RSApub. */ static int rpubk_init(B_KEY_OBJ rpubk, RSApub const *pub, PGPMemoryMgrRef mgr) { A_RSA_KEY kdata; PGPByte *buf; PGPSize bufsize; int err; bufsize = bnBytes(&pub->n) + bnBytes(&pub->e); buf = PGPNewSecureData( mgr, bufsize, 0 ); kdata.modulus.data = buf; kdata.modulus.len = bnBytes(&pub->n); kdata.exponent.data = buf + kdata.modulus.len; kdata.exponent.len = bnBytes(&pub->e); bnExtractBigBytes (&pub->n, kdata.modulus.data, 0, kdata.modulus.len); bnExtractBigBytes (&pub->e, kdata.exponent.data, 0, kdata.exponent.len); err = B_SetKeyInfo (rpubk, KI_RSAPublic, (POINTER)&kdata); pgpAssert (err == 0); pgpClearMemory (buf, bufsize); PGPFreeData (buf); return err; }
VOID KMFreePasskey (PGPByte* pbyte, PGPSize size) { if (pbyte) { FillMemory (pbyte, size, 0x00); PGPFreeData (pbyte); } }
VOID secFree (VOID* p) { if (p) { FillMemory ((char *)p,lstrlen((char *)p), '\0'); PGPFreeData ((char *)p); } }
static void secFree (void* p) { if (p) { memset ((char *)p, '\0', strlen((char *)p)); PGPFreeData ((char *)p); } }
PGPError pgpPlatformFreeDirectoryIter( PFLDirectoryIterRef iter ) { PGPValidatePtr( iter ); PGPFreeData( iter ); return kPGPError_NoErr; }
void pgpFileReadDestroy (PGPFileRead *context) { pgpAssert (context); if (context->closeFlag) (void) pgpFileClose (context->file); PGPFreeData( context ); }
int x509CMSDeallocProc ( PKIMemoryMgr *mem, void *allocation ) { (void) mem; PGPFreeData (allocation); return 0; }
/* destoys the bignum and all memory it uses */ PGPError PGPFreeBigNum( PGPBigNumRef bn ) { PGPError err = kPGPError_NoErr; pgpValidateBigNum( bn ); bnEnd( &bn->bn ); err = PGPFreeData( bn ); return( err ); }
/* take a FILE* and convert it to a PGPFile* */ static PGPFile * doOpen( PGPContextRef cdkContext, FILE *file, int fflags) { PGPFile *fp; File *ffp; struct stat buf; PGPMemoryMgrRef memoryMgr = PGPGetContextMemoryMgr( cdkContext ); if (!file) return NULL; fp = (PGPFile *)PGPNewData( memoryMgr, sizeof (*fp), kPGPMemoryMgrFlags_Clear); if (!fp) return NULL; fp->context = cdkContext; fp->dataType = kPGPFileDataType_Unknown; ffp = (File *)PGPNewData( memoryMgr, sizeof (*ffp), kPGPMemoryMgrFlags_Clear); if (!ffp) { PGPFreeData( fp ); return NULL; } if (fstat (fileno (file), &buf) == 0 && (S_IFMT & buf.st_mode) == S_IFREG) ffp->maybeSize = buf.st_size; else ffp->maybeSize = -1; rewind (file); ffp->f = file; ffp->flags = fflags; fp->priv = ffp; fp->read = stdioRead; fp->write = stdioWrite; fp->flush = stdioFlush; fp->close = fileClose; fp->tell = stdioTell; fp->seek = stdioSeek; fp->eof = fileEof; fp->sizeAdvise = fileSizeAdvise; fp->error = fileError; fp->clearError = fileClearError; fp->write2read = fileWrite2read; fp->cfb = fileCfb; return fp; }
static PGPError sRenameProc( PFLFileSpecRef ref, const char * newName) { PGPError err = kPGPError_NoErr; MyData * oldDataCopy = NULL; PGPMemoryMgrRef memoryMgr = ref->memoryMgr; /* save the old data in case the rename fails */ /* also needed for rename (see below) */ oldDataCopy = (MyData *)PGPNewData( memoryMgr, MyDataSize( ref ), 0); if ( NULL!=(int)( oldDataCopy ) ) { pgpCopyMemory( GetMyData( ref ), oldDataCopy, MyDataSize( ref ) ); /* this changes the current data */ err = sSetNameProc( ref, newName ); if ( rename( oldDataCopy->path, GetMyData( ref )->path ) != 0) { err = kPGPError_FileOpFailed; /* XXX Improve error */ /* put old path back in place of new one */ PGPFreeData( GetMyData( ref ) ); SetMyData( ref, oldDataCopy ); } else { PGPFreeData( oldDataCopy ); } } else { err = kPGPError_OutOfMemory; } return( err ); }
PGPError PGPFreeIO( PGPIORef ref ) { PGPError err = kPGPError_NoErr; PGPValidateIO( ref ); err = CallDestroy( ref, ref->vtbl); PGPFreeData( ref ); return( err ); }
/*____________________________________________________________________________ ____________________________________________________________________________*/ PGPError PGPFreeCBCContext( PGPCBCContextRef ref ) { PGPError err = kPGPError_NoErr; PGPValidateCBC( ref ); PGPFreeSymmetricCipherContext( ref->symmetricRef ); pgpClearMemory( ref, sizeof( *ref ) ); PGPFreeData( ref ); return( err ); }
PGPError pgpPlatformFreeDirectoryIter( PFLDirectoryIterRef iter ) { PGPError err = kPGPError_NoErr; PGPValidatePtr( iter ); if ( closedir( iter->dirRef ) != 0 ) err = kPGPError_FileOpFailed; /* XXX Better error code? */ PFLFreeFileSpec( iter->parentDir ); PGPFreeData( iter ); return err; }
LPSTR __cdecl _pgp_encrypt_key(LPCSTR szPlainMsg, LPCSTR pgpKey) { #if defined(_WIN64) return 0; #else LPSTR szEncMsg = 0; PGPSize dwEncMsgLen; PGPUInt32 dwKeys; PGPKeyDBRef PublicKeyDB; if (CheckPGPError(_pgp_import_key(&PublicKeyDB,pgpKey))) return 0; PGPKeyIterRef KeyIterRef; PGPNewKeyIterFromKeyDB(PublicKeyDB, &KeyIterRef); PGPKeyDBObjRef PublicKey; PGPKeyIterNextKeyDBObj(KeyIterRef, kPGPKeyDBObjType_Key, &PublicKey); PGPCountKeysInKeyDB(PublicKeyDB, &dwKeys); if(dwKeys==0) { PGPFreeKeyIter(KeyIterRef); PGPFreeKeyDB(PublicKeyDB); return 0; } PGPError err = PGPEncode(pgpContext, PGPOInputBuffer(pgpContext, szPlainMsg, lstrlen(szPlainMsg)), PGPOArmorOutput(pgpContext, TRUE), PGPOAllocatedOutputBuffer(pgpContext, (LPVOID *)&szEncMsg, 16384, &dwEncMsgLen), PGPOEncryptToKeyDBObj(pgpContext, PublicKey), PGPOVersionString(pgpContext, szVersionStr), PGPOLastOption(pgpContext)); PGPFreeKeyIter(KeyIterRef); PGPFreeKeyDB(PublicKeyDB); if (CheckPGPError(err)) return 0; LPSTR szMsg = (LPSTR) LocalAlloc(LPTR,dwEncMsgLen+1); _pgp_memcpy(szMsg, szEncMsg, dwEncMsgLen); szMsg[dwEncMsgLen] = 0; PGPFreeData((LPVOID)szEncMsg); return szMsg; #endif }
PGPError KMGetConventionalPhrase ( PGPContextRef context, HWND hwnd, LPSTR pszPrompt, LPSTR* ppszPhrase) { PGPError err = kPGPError_BadParams; PGPOptionListRef optionList = kInvalidPGPOptionListRef; if (!ppszPhrase) return err; err = PGPBuildOptionList (context, &optionList, PGPOUIOutputPassphrase (context, ppszPhrase), PGPOUIParentWindowHandle (context, hwnd), PGPOLastOption (context)); if (IsntPGPError (err)) { // If we have a prompt, use it if (NULL!=(int) (pszPrompt)) { err = PGPAppendOptionList (optionList, PGPOUIDialogPrompt (context, pszPrompt), PGPOLastOption (context)); } if (IsntPGPError (err)) { err = PGPConventionalDecryptionPassphraseDialog (context, optionList, PGPOLastOption (context)); } } if (IsPGPError (err)) { if (*ppszPhrase) { PGPFreeData (*ppszPhrase); *ppszPhrase = NULL; } } if (PGPOptionListRefIsValid (optionList)) PGPFreeOptionList (optionList); return err; }
PGPError pgpPlatformOpenFileSpecAsFILE( PFLFileSpecRef spec, const char * openMode, FILE ** fileOut ) { PGPError err = kPGPError_NoErr; FILE * stdioFILE = NULL; char * fullPath; PGPValidatePtr( fileOut ); *fileOut = NULL; PFLValidateFileSpec( spec ); PGPValidatePtr( openMode ); PGPValidateParam( spec->type == kPFLFileSpecFullPathType ); err = PFLGetFullPathFromFileSpec( spec, &fullPath ); if ( IsntPGPError( err ) ) { stdioFILE = fopen( fullPath, openMode ); PGPFreeData( fullPath ); if ( NULL==(int)( stdioFILE ) ) { if (errno == EACCES #ifdef EROFS || errno == EROFS #endif ) { err = kPGPError_FilePermissions; } else if (errno == ENOENT) { err = kPGPError_FileNotFound; } else { err = kPGPError_FileOpFailed; } } } *fileOut = stdioFILE; return( err ); }
LPSTR __cdecl _pgp_encrypt_keydb(LPCSTR szPlainMsg, PVOID pgpKeyID) { PGPKeyID *RemoteKeyID = (PGPKeyID *) pgpKeyID; LPSTR szEncMsg = 0; DWORD dwEncMsgLen; ClearPGPError(); if(!pgpKeyDB) return 0; #if (PGP_WIN32 < 0x700) PGPFilterRef IDFilter; PGPNewKeyIDFilter(pgpContext, RemoteKeyID, &IDFilter); PGPKeySetRef PublicKey; PGPFilterKeySet(pgpKeyDB, IDFilter, &PublicKey); #else PGPKeyDBObjRef PublicKey; PGPFindKeyByKeyID(pgpKeyDB, RemoteKeyID, &PublicKey); #endif PGPError err = PGPEncode(pgpContext, PGPOInputBuffer(pgpContext, szPlainMsg, lstrlen(szPlainMsg)), PGPOArmorOutput(pgpContext, TRUE), PGPOAllocatedOutputBuffer(pgpContext, (LPVOID *)&szEncMsg, 16384, (PGPUInt32 *)&dwEncMsgLen), #if (PGP_WIN32 < 0x700) PGPOEncryptToKeySet(pgpContext, PublicKey), #else PGPOEncryptToKeyDBObj(pgpContext, PublicKey), #endif PGPOVersionString(pgpContext, szVersionStr), PGPOLastOption(pgpContext)); #if (PGP_WIN32 < 0x700) PGPFreeKeySet(PublicKey); PGPFreeFilter(IDFilter); #endif if (CheckPGPError(err)) return 0; LPSTR szMsg = (LPSTR) LocalAlloc(LPTR,dwEncMsgLen+1); _pgp_memcpy(szMsg, szEncMsg, dwEncMsgLen); szMsg[dwEncMsgLen] = 0; PGPFreeData((LPVOID)szEncMsg); return szMsg; }
PGPError pgpPlatformFreeDirectoryIter( PFLDirectoryIterRef iter ) { PGPError err = kPGPError_NoErr; PGPValidatePtr( iter ); PFLFreeFileSpec( iter->parentDir ); if( iter->fileSearch != INVALID_HANDLE_VALUE ) FindClose( iter->fileSearch ); PGPFreeData( iter ); return err; }
PGPError PGPFreeDefaultMemoryMgr(PGPDefaultMemoryMgrRef defaultRef) { PGPMemoryMgrRef mgr; if (!sDefaultMemoryMgrIsValid(defaultRef)) return kPGPError_BadParams; sFreeDefaultMemoryMgrList(defaultRef); mgr = defaultRef->internalMemoryMgr; PGPFreeData(defaultRef); PGPFreeMemoryMgr(mgr); return kPGPError_NoErr; }
PGPError dokeycheck(struct pgpmainBones *mainbPtr, char *useridStr, PGPFileSpecRef ringFileSpec) { PGPKeySetRef ringSet = NULL; char *ringfile = NULL; PGPError err, er2; struct pgpenvBones *envbPtr = mainbPtr->envbPtr; struct pgpfileBones *filebPtr = mainbPtr->filebPtr; PGPEnv *env = envbPtr->m_env; PGPInt32 pri; PGPBoolean quietmode = pgpenvGetInt( env, PGPENV_NOOUT, &pri, &err); PGPBoolean compatible = envbPtr->compatible; err = PGPGetFullPathFromFileSpec( ringFileSpec, &ringfile ); pgpAssertNoErr(err); err = PGPOpenKeyRing(mainbPtr->pgpContext, 0, ringFileSpec, &ringSet); #if 0 err = pgpOpenKeyringsFromPubringSpec( mainbPtr, ringFileSpec, &ringSet, 0); #endif 0 if( IsPGPError(err) ) goto done; if (!quietmode) fprintf(filebPtr->pgpout, LANG("\nKey ring: '%s'"), ringfile); mainbPtr->workingRingSet=ringSet; err = pgpDoCheckKeyRing(mainbPtr, useridStr); pgpAssertNoErr(err); done: if (ringfile) er2 = PGPFreeData( ringfile ); if (ringSet) er2 = PGPFreeKeySet( ringSet ); mainbPtr->workingRingSet = NULL; if( !compatible && IsPGPError(err) && pgpenvGetInt( env, PGPENV_VERBOSE, &pri, &er2) ) pgpShowError(filebPtr, err, __FILE__,__LINE__); return err; }
/* test reallocation, then dispose of the ptr */ static void sTestUsingPtr( PGPMemoryMgrRef mgr, void * data ) { PGPError err = kPGPError_NoErr; (void)mgr; err = PGPReallocData( mgr, &data, 20000, 0 ); pgpAssertNoErr( err ); err = PGPReallocData( mgr, &data, 500, 0 ); pgpAssertNoErr( err ); err = PGPReallocData( mgr, &data, 0, 0 ); pgpAssertNoErr( err ); err = PGPReallocData( mgr, &data, 20001, 0 ); pgpAssertNoErr( err ); PGPFreeData( data ); }
/*____________________________________________________________________________ Create a new PGPIO object. The vtbl and object size are specified so that subclasses can use this routine. ____________________________________________________________________________*/ PGPError pgpNewIOFromVTBL( PGPMemoryMgrRef context, PGPIOVtbl const * vtbl, PGPSize size, void * data, PGPIORef * outRef ) { PGPError err = kPGPError_NoErr; PGPIORef newRef; PGPValidatePtr( outRef ); *outRef = NULL; PGPValidateMemoryMgr( context ); newRef = (PGPIORef)PGPNewData( context, size, kPGPMemoryMgrFlags_Clear ); if ( NULL!=(int)( newRef ) ) { /* use cast so we can assign to this const * const field */ *(PGPIOVtbl const **)(&newRef->vtbl) = vtbl; newRef->context = context; newRef->magic = kPGPIOMagic; /* initialize remaining fields in sInitProc */ err = CallInit( newRef, newRef->vtbl, data ); if ( IsPGPError( err ) ) { CallDestroy( newRef, newRef->vtbl); PGPFreeData( newRef ); newRef = NULL; } } else { err = kPGPError_OutOfMemory; } *outRef = newRef; return( err ); }
PGPError pgpPlatformNewDirectoryIter( PFLConstFileSpecRef parentDir, PFLDirectoryIterRef * outIter ) { PGPMemoryMgrRef memoryMgr = parentDir->memoryMgr; PGPError err = kPGPError_NoErr; FSSpec spec; PFLDirectoryIterRef newIter = NULL; CInfoPBRec cpb; *outIter = NULL; PGPValidateParam( parentDir->type == kPFLFileSpecMacType ); PGPValidateMemoryMgr( memoryMgr ); err = GetSpec( parentDir, &spec, &cpb ); if( IsntPGPError( err ) ) { newIter = (PFLDirectoryIterRef)PGPNewData( memoryMgr, sizeof( *newIter ), 0 ); if ( NULL!=(int)( newIter ) ) { pgpAssert( cpbIsFolder( &cpb ) ); newIter->memoryMgr = memoryMgr; newIter->vRefNum = spec.vRefNum; newIter->parID = cpb.dirInfo.ioDrDirID; newIter->dirIndex = 1; } else { err = kPGPError_OutOfMemory; } } if ( IsntPGPError( err ) ) *outIter = newIter; else if ( NULL!=(int)( newIter ) ) PGPFreeData( newIter ); return err; }