static void bignumToInternal( LONG *outData, int *outDataLength, const BYTE *inData, const int inDataLength ) { int inIndex, outIndex = 0, i; assert( isWritePtr( outData, CRYPT_MAX_PKCSIZE ) ); assert( isWritePtr( outDataLength, sizeof( int ) ) ); assert( isReadPtr( inData, inDataLength ) ); REQUIRES_V( inDataLength > 0 && inDataLength <= CRYPT_MAX_PKCSIZE ); for( i = 0; i < CRYPT_MAX_PKCSIZE / sizeof( LONG ); i++ ) outData[ i ] = 0L; for( inIndex = 0; inIndex < inDataLength; inIndex += sizeof( LONG ) ) { outData[ outIndex++ ] = mgetLong( inData ); } *outDataLength = outIndex; }
// Assumes that VerifyPackageIntegrity() has been used. Returns TRUE, if successful (otherwise FALSE). // Creates a table of pointers to buffers containing the following objects for each file: // filename size, filename (not null-terminated!), file size, file CRC-32, uncompressed file contents. // For details, see the definition of the DECOMPRESSED_FILE structure. BOOL SelfExtractInMemory (char *path) { int filePos = 0, fileNo = 0; int fileDataEndPos = 0; int fileDataStartPos = 0; unsigned int uncompressedLen = 0; unsigned int compressedLen = 0; unsigned char *compressedData = NULL; unsigned char *bufPos = NULL, *bufEndPos = NULL; FreeAllFileBuffers(); fileDataEndPos = (int) FindStringInFile (path, MagEndMarker, strlen (MagEndMarker)); if (fileDataEndPos < 0) { Error ("CANNOT_READ_FROM_PACKAGE"); return FALSE; } fileDataEndPos--; fileDataStartPos = (int) FindStringInFile (path, MAG_START_MARKER, strlen (MAG_START_MARKER)); if (fileDataStartPos < 0) { Error ("CANNOT_READ_FROM_PACKAGE"); return FALSE; } fileDataStartPos += strlen (MAG_START_MARKER); filePos = fileDataStartPos; // Read the stored total size of the uncompressed data if (!LoadInt32 (path, &uncompressedLen, filePos)) { Error ("CANNOT_READ_FROM_PACKAGE"); return FALSE; } filePos += 4; // Read the stored total size of the compressed data if (!LoadInt32 (path, &compressedLen, filePos)) { Error ("CANNOT_READ_FROM_PACKAGE"); return FALSE; } filePos += 4; if (compressedLen != fileDataEndPos - fileDataStartPos - 8 + 1) { Error ("DIST_PACKAGE_CORRUPTED"); } DecompressedData = malloc (uncompressedLen + 524288); // + 512K reserve if (DecompressedData == NULL) { Error ("ERR_MEM_ALLOC"); return FALSE; } bufPos = DecompressedData; bufEndPos = bufPos + uncompressedLen - 1; compressedData = LoadFileBlock (path, filePos, compressedLen); if (compressedData == NULL) { free (DecompressedData); DecompressedData = NULL; Error ("CANNOT_READ_FROM_PACKAGE"); return FALSE; } // Decompress the data if (DecompressBuffer (DecompressedData, compressedData, compressedLen) != uncompressedLen) { Error ("DIST_PACKAGE_CORRUPTED"); goto sem_end; } while (bufPos <= bufEndPos && fileNo < NBR_COMPRESSED_FILES) { // Filename length Decompressed_Files[fileNo].fileNameLength = mgetWord (bufPos); // Filename Decompressed_Files[fileNo].fileName = bufPos; bufPos += Decompressed_Files[fileNo].fileNameLength; // CRC-32 of the file Decompressed_Files[fileNo].crc = mgetLong (bufPos); // File length Decompressed_Files[fileNo].fileLength = mgetLong (bufPos); // File content Decompressed_Files[fileNo].fileContent = bufPos; bufPos += Decompressed_Files[fileNo].fileLength; // Verify CRC-32 of the file (to verify that it didn't get corrupted while creating the solid archive). if (Decompressed_Files[fileNo].crc != GetCrc32 (Decompressed_Files[fileNo].fileContent, Decompressed_Files[fileNo].fileLength)) { Error ("DIST_PACKAGE_CORRUPTED"); goto sem_end; } fileNo++; } if (fileNo < NBR_COMPRESSED_FILES) { Error ("DIST_PACKAGE_CORRUPTED"); goto sem_end; } free (compressedData); return TRUE; sem_end: FreeAllFileBuffers(); free (compressedData); return FALSE; }