Using Vice without Steam: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
m (→‎What is this?: remove terminology that nobody uses)
 
(25 intermediate revisions by 11 users not shown)
Line 1: Line 1:
== What is this? ==
== What is this? ==
This is a [[Steam port]] of [[Vice|VICE]] that is built to not depend on Steam. This modification works on Windows and Linux.
This is a modified version of [[Vice|VICE]] that is built to not depend on Steam. This modification works on Windows and Linux.
 
== Pre-Built binaries ==
* http://3dwire.net/bin/ice.zip '''(Link is dead)'''
* https://github.com/foobarhl/vice_standalone/raw/master/bin/vice '''Built on Ubuntu 12.04.2 LTS'''


== Compiling on Windows ==
== Compiling on Windows ==
Line 10: Line 14:
== Compiling on Linux ==
== Compiling on Linux ==
* Copy the makefile into a file called Makefile
* Copy the makefile into a file called Makefile
* edit the Makefile to refleft the path to your SDK_ROOT/public/ directory
* edit the Makefile to reflect the path to your SDK_ROOT/public/ directory
* make
* make


Line 36: Line 40:


#define MAX_ICE_KEY 8
#define MAX_ICE_KEY 8
#define MAX_EXTENTION 16
#define MAX_EXTENSION 16
static char g_ICEKey[MAX_ICE_KEY];
static char g_ICEKey[MAX_ICE_KEY];
static char g_Extension[MAX_EXTENTION];
static char g_Extension[MAX_EXTENSION];


#ifdef WIN32
#ifdef WIN32
Line 52: Line 56:
void Usage( void )
void Usage( void )
{
{
fprintf( stdout, "Usage: ice <-d> <-x ext> [-k IceKey(8 bit)] [file]\n" );
printf( "Usage: ice <-d> <-x ext> [-k IceKey(8 byte)] [file]\n" );
fprintf( stdout, "Default action: Encrypt. \n" );
printf( "Default action: Encrypt. \n" );
fprintf( stdout, "-d : Decrypt a file. \n" );
printf( "-d : Decrypt a file. \n" );
fprintf( stdout, "-x : Extention to use as output. \n" );
printf( "-x : Extension to use as output. \n" );
fprintf( stdout, "-k : You need to specify your 8 bit Ice Encryption Key. \n" );
printf( "-k : You need to specify your 8 byte Ice Encryption Key. \n" );
fprintf( stdout, "-h : Print the help menu, and stop.\n" );
printf( "-h : Print the help menu, and stop.\n" );
}
}


Line 66: Line 70:
}
}


void SetExtention(char *dest, size_t length, const char *ext)
void SetExtension(char *dest, size_t length, const char *ext)
{
{
//Start at the end till we hit a .
//Start at the end till we hit a .
Line 95: Line 99:
//By default we output .ctx
//By default we output .ctx
strncpy( g_Extension, ".ctx",MAX_EXTENTION );
strncpy( g_Extension, ".ctx",MAX_EXTENSION );
memset(g_ICEKey,0,MAX_ICE_KEY);
memset(g_ICEKey,0,MAX_ICE_KEY);


Line 112: Line 116:
else if( STRING_CMP( argv[i], "-x" ) == 0 )
else if( STRING_CMP( argv[i], "-x" ) == 0 )
{
{
//Extention
//Extension
i++;
i++;


if ( strlen( argv[i] ) > MAX_EXTENTION )
if ( strlen( argv[i] ) > MAX_EXTENSION )
{
{
Exit("Your Extention is too big.\n");
Exit("Your Extension is too big.\n");
}
}


strncpy( g_Extension, argv[i], MAX_EXTENTION );
strncpy( g_Extension, argv[i], MAX_EXTENSION );
}
}
else if( STRING_CMP( argv[i], "-k" ) == 0 )
else if( STRING_CMP( argv[i], "-k" ) == 0 )
Line 208: Line 212:
memcpy( p2, p1, bytesLeft );
memcpy( p2, p1, bytesLeft );


size_t outLength = strlen(argv[i]) + MAX_EXTENTION + 1;
size_t outLength = strlen(argv[i]) + MAX_EXTENSION + 1;
char *pOutPath = (char *)malloc(outLength);
char *pOutPath = (char *)malloc(outLength);
strncpy(pOutPath,argv[i],outLength);
strncpy(pOutPath,argv[i],outLength);


SetExtention(pOutPath, outLength, g_Extension);
SetExtension(pOutPath, outLength, g_Extension);


pFile = fopen (pOutPath , "w");
pFile = fopen (pOutPath , "wb");
if(pFile == NULL)
if(pFile == NULL)
{
{
Line 233: Line 237:
== Linux Makefile ==
== Linux Makefile ==
<pre>
<pre>
#Simple Makefile for compiling on linux
#Simple Makefile for compiling on Linux
CPP = g++
CPP = g++
PUBLIC=../../public
PUBLIC=../../public
CPPFLAGS = ${PUBLIC}


ice:
ice:
Line 245: Line 248:
</pre>
</pre>


== Wildcard Version by [[User:Red comet|Red Comet]] ==
== (Optional) Perl Script to make life easier ==
I really like what you did with vice, so I took my favorite part of steam vice and added it to your vice.
I use Env. Variables in all my scripts because of multiple developers, so you can either hardcode the variables, or set the env. variables on your system (see msdn docs. for that). Also, to take this even further, on my system I created a new MSVC project, then changed it to a utility project (leaving me with just build events); I then called the perl script as my post-build and MSVC now does everything for me in my build process.
 
This new program will accept the wildcard ' * ' in the filename, so you can put this exe in with all your txt's and encrypt them all at once.
 
Instructions:
 
Copy this new Main.cpp file into your old one, completly replacing the old one
 
Make a new header file called osdir.h and copy the contents of the second section of code below into it.
 
Compile
 
'''''Not sure if it works in Linux yet, but it should'''''
 
Credits to bvh, whoever you are, and Google
 
Main.cpp
<pre>
<pre>
#Main.cpp
#!/usr/bin/perl
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
# easy script that compiles our scripts folder and then moves them to our mod directory!
//
// Purpose: Standalone utility to encrypt files with ice encryption, that doesn't
// depend on Steam.
//
// Author: Valve Software and Scott Loyd (scottloyd@gmail.com).
// Tested and proofread by Me2.
// Depends on: Just needs public/IceKey.cpp to be compiled/linked with it
// $NoKeywords: $
//
//=============================================================================//
#include "stdafx.h"
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "osdir.h"
#include "IceKey.H"
 
// Globals
static bool g_Encrypt = true; //By default we encrypt
 
#define MAX_ICE_KEY 8
#define MAX_EXTENTION 16
static char g_ICEKey[MAX_ICE_KEY];
static char g_Extension[MAX_EXTENTION];


#ifdef WIN32
use warnings;
#define STRING_CMP stricmp
use strict;
#else
#define STRING_CMP strcasecmp
#undef NULL
#define NULL 0
#endif


bool DEncrypt(const char* filename);
use File::Copy;


//----- Helpers -----
void Usage( void )
{
fprintf( stdout, "Usage: ice <-d> <-x ext> [-k IceKey(8 bit)] [file]\n" );
fprintf( stdout, "Default action: Encrypt. \n" );
fprintf( stdout, "-d : Decrypt a file. \n" );
fprintf( stdout, "-x : Extention to use as output. \n" );
fprintf( stdout, "-k : You need to specify your 8 bit Ice Encryption Key. \n" );
fprintf( stdout, "-h : Print the help menu, and stop.\n" );
}


void Exit(const char *msg)
our $outExt = ".ctx";
{
fprintf( stderr, msg );
exit( 1 );
}
 
void SetExtention(char *dest, size_t length, const char *ext)
{
//Start at the end till we hit a .
//if we reach 0 without a .  just append the extension; one must not have existed.
size_t mover = length;
 
while( (*(dest + mover) != '.') && (mover > 0))
mover--;
 
if(mover == 0)
strcat(dest,ext);
else
{
strcpy(dest + mover,ext);
}
}


/*
our $baseOutput = $ENV{'MOD_CONTENT'};
The entry point, see usage for I/O
die("Could not find MOD_CONTENT envirornment variable.\n") if !$baseOutput;
*/
our $outputDir = $baseOutput."\\scripts";
int main(int argc, char* argv[])
{
if(argc < 2)
{
Usage();
exit( 0 );
}
//By default we output .ctx
strncpy( g_Extension, ".ctx",MAX_EXTENTION );
memset(g_ICEKey,0,MAX_ICE_KEY);


int i = 1;
our $inputDir = $ENV{'CODE_SCRIPTS'};
while( i < argc )
die("Could not find CODE_SCRIPTS envirornment variable.\n") if !$inputDir;
{
if( STRING_CMP( argv[i], "-h" ) == 0 )
{
Usage();
exit( 0 );
}
else if( STRING_CMP( argv[i], "-d" ) == 0 )
{
g_Encrypt = false;
}
else if( STRING_CMP( argv[i], "-x" ) == 0 )
{
//Extention
i++;


if ( strlen( argv[i] ) > MAX_EXTENTION )
our $iceKey = $ENV{'ICE_KEY'};
{
die("Could not find ICE_KEY envirornment variable.\n") if !$iceKey;
Exit("Your Extention is too big.\n");
}


strncpy( g_Extension, argv[i], MAX_EXTENTION );
}
else if( STRING_CMP( argv[i], "-k" ) == 0 )
{
//Key
i++;


if ( strlen( argv[i] ) != MAX_ICE_KEY )
our $devToolPath = $ENV{'CODE_DEVTOOLS'};
{
die("Could not find CODE_DEVTOOLS envirornment variable.\n") if !$devToolPath;
Exit("Your ICE key needs to be 8 characters long.\n");
}


strncpy( g_ICEKey, argv[i], MAX_ICE_KEY );
printf(" ** Encrypting scripts and copying them into your mod ** \n");
}
else
{
break;
}
i++;
}


if(g_ICEKey[0] == '\0') {
my $command = "$devToolPath\\ice -x $outExt -k $iceKey ";
Exit("You need to specify a key.\n");
}
//Parse files starting from current arg position
if(argv[i] == NULL && (strlen(argv[i]) < 1))
Exit("Was not about to find a file to parse\n");


opendir DH, $inputDir or die "Could not open code-scripts directory\n";


//Directory enumeration by Red Comet
while ($_ = readdir(DH))
//Thanks Google and bvh for directory class
if( strstr(argv[i],"*") != NULL ){
oslink::directory dir("."); //Create list of files inside current directory
char* pch = strstr(argv[i],"."); //Get pointer to the '.' in the file extension we want
char sExt[5] = "";
 
strncpy(sExt,pch,4);
while (dir){
//std::cout << "Heres a file: " << dir.next() << std::endl;
//Check each file to see if it matches wildcard
std::string nFile;
nFile = dir.next();
if( strstr(nFile.c_str(),sExt) != NULL ){
if(DEncrypt(nFile.c_str()))
std::cout << "Handled file: " << nFile << " successfully." << std::endl;
}
 
}
}else{
if(DEncrypt(argv[i]))
std::cout << "Handled file: " << argv[i] << " successfully." << std::endl;
}
//End Red Comet code
}
 
 
bool DEncrypt(const char* filename)
{
//Open allocate/read a file into memory
FILE *pFile;
pFile = fopen (filename, "rb");
if(! pFile)
Exit("Failed to open input file\n");
 
long lFileSize; //Size of input file
unsigned char *pBuff; //Holds the input file contents
unsigned char *pOutBuff; //Holds the output goodies
 
// obtain file size.
fseek (pFile , 0 , SEEK_END);
lFileSize= ftell (pFile);
rewind (pFile);
 
// allocate memory to contain the whole file.
pBuff = (unsigned char*) malloc (lFileSize);
pOutBuff = (unsigned char*) malloc (lFileSize);
 
if (pBuff == NULL || pOutBuff == NULL)
{
{
fclose(pFile);
# we don't want to process . or .. directory holders.
std::cout << "Could not allocate buffer" << std::endl;
next if $_ eq ".";
next if $_ eq "..";
next if -d $_;
next if $_ !~ m/.txt$/;
my $inFile = $inputDir."\\".$_;
system($command.$inFile);
#printf "Command: ".$command.$inFile."\n";
#Get a filename/path without the extension, add the extension to the end.
my $outFile = $outputDir."\\".$_;
$outFile =~ s/(.*).txt$/$1.ctx/;
$inFile =~ s/(.*).txt$/$1.ctx/;
#printf "InFile: ".$inFile."\n";
#printf "OutFile: ".$outFile."\n";
move($inFile,$outFile);
}
}
 
closedir DH;
// copy the file into the buffer.
fread (pBuff,1,lFileSize,pFile);
//clean the output buffer
memset(pOutBuff,NULL,lFileSize);
 
fclose(pFile);
 
//Lets start the ice goodies!
IceKey ice( 0 ); // level 0 = 64bit key
ice.set( (unsigned char*) g_ICEKey ); // set key
 
int blockSize = ice.blockSize();
 
unsigned char *p1 = pBuff;
unsigned char *p2 = pOutBuff;
 
// encrypt data in 8 byte blocks
int bytesLeft = lFileSize;
 
while ( bytesLeft >= blockSize )
{
if ( g_Encrypt )
ice.encrypt( p1, p2 );
else
ice.decrypt( p1, p2 );
 
bytesLeft -= blockSize;
p1+=blockSize;
p2+=blockSize;
}
 
//The end chunk doesn't get an encryption?  that sux...
memcpy( p2, p1, bytesLeft );
 
size_t outLength = strlen(filename) + MAX_EXTENTION + 1;
char *pOutPath = (char *)malloc(outLength);
strncpy(pOutPath,filename,outLength);
 
SetExtention(pOutPath, outLength, g_Extension);
 
pFile = fopen (pOutPath , "w");
if(pFile == NULL)
{
fprintf( stderr, "Was not able to open output file for writing.\n" );
free(pBuff);
free(pOutBuff);
free(pOutPath);
return false;
}
 
fwrite (pOutBuff , 1 , lFileSize , pFile);
fclose (pFile);
 
dealloc:
free(pBuff);
free(pOutBuff);
free(pOutPath);
 
return true;
}
</pre>
</pre>


osdir.h
== See also ==
<pre>
* [[Vice_Standalone_With_Wildcards|Vice with wildcard(*) support]] - [[User:Red comet|Red Comet]]'s version
# osdir.h
* [[Vice]]
/**
* Copyright (C) 2002 Bart Vanhauwaert
*
* Permission to use, copy, modify, distribute and sell this software
* for any purpose is hereby granted without fee. This license
* includes (but is not limited to) standalone compilation or as part
* of a larger project.
*
* This software is provided "as is" without express or implied warranty.
*
* For a full statement on warranty and terms and conditions for
* copying, distribution and modification, please see the comment block
* at the end of this file.
*
* Version 1
*
*/


#ifndef OSLINK_OSDIR_HEADER_H_
[[Category:Third Party Tools]]
#define OSLINK_OSDIR_HEADER_H_
 
#if defined(unix) || defined(__unix) || defined(__unix__)
#define OSLINK_OSDIR_POSIX
#elif defined(_WIN32)
#define OSLINK_OSDIR_WINDOWS
#else
#define OSLINK_OSDIR_NOTSUPPORTED
#endif
 
#include <string>
 
#if defined(OSLINK_OSDIR_NOTSUPPORTED)
 
namespace oslink
{
class directory
{
public:
directory(const std::string&) { }
operator void*() const { return (void*)0; }
std::string next() { return ""; }
};
}
 
#elif defined(OSLINK_OSDIR_POSIX)
 
#include <sys/types.h>
#include <dirent.h>
 
namespace oslink
{
class directory
{
public:
directory(const std::string& aName)
: handle(opendir(aName.c_str())), willfail(false)
{
if (!handle)
willfail = true;
else
{
dirent* entry = readdir(handle);
if (entry)
current = entry->d_name;
else
willfail = true;
}
}
~directory()
{
if (handle)
closedir(handle);
}
operator void*() const
{
return willfail ? (void*)0:(void*)(-1);
}
std::string next()
{
std::string prev(current);
dirent* entry = readdir(handle);
if (entry)
current = entry->d_name;
else
willfail = true;
return prev;
}
private:
DIR* handle;
bool willfail;
std::string current;
};
}
 
#elif defined(OSLINK_OSDIR_WINDOWS)
 
#include <windows.h>
#include <winbase.h>
 
namespace oslink
{
class directory
{
public:
directory(const std::string& aName)
: handle(INVALID_HANDLE_VALUE), willfail(false)
{
// First check the attributes trying to access a non-directory with
// FindFirstFile takes ages
DWORD attrs = GetFileAttributes(aName.c_str());
if ( (attrs == 0xFFFFFFFF) || ((attrs && FILE_ATTRIBUTE_DIRECTORY) == 0) )
{
willfail = true;
return;
}
std::string Full(aName);
// Circumvent a problem in FindFirstFile with c:\\* as parameter
if ( (Full.length() > 0) && (Full[Full.length()-1] != '\\') )
Full += "\\";
WIN32_FIND_DATA entry;
handle = FindFirstFile( (Full+"*").c_str(), &entry);
if (handle == INVALID_HANDLE_VALUE)
willfail = true;
else
current = entry.cFileName;
}
~directory()
{
if (handle != INVALID_HANDLE_VALUE)
FindClose(handle);
}
 
operator void*() const
{
return willfail ? (void*)0:(void*)(-1);
}
std::string next()
{
std::string prev = current;
WIN32_FIND_DATA entry;
int ok = FindNextFile(handle, &entry);
if (!ok)
willfail = true;
else
current = entry.cFileName;
return current;
}
private:
HANDLE handle;
bool willfail;
std::string current;
};
}
 
 
#endif
 
#endif
 
/**
*
* The "library", below, refers to the collection of software functions
* and/or data contained in this file, prepared so as to be conveniently
* compiled and linked with application programs (which use some of those
* functions and data) to form executables.
*
*                            NO WARRANTY
*                             
* 1. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
* WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
* EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
* OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
* LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
* THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
*
* 2. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
* WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
* AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
* FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
* LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
* RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
* FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
* SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGES.
*
* END OF TERMS AND CONDITIONS
*
*/
 
</pre>
 
==See Also==
* [[Vice]]

Latest revision as of 15:28, 9 August 2023

What is this?

This is a modified version of VICE that is built to not depend on Steam. This modification works on Windows and Linux.

Pre-Built binaries

Compiling on Windows

  • First you need to create a new Empty VisualC++ Console Project that will compile this code into an executable.
  • Add public/IceKey.cpp into your project
  • Setup the include paths in your settings to include public/ (for the header file)
  • Copy the code below into main.cpp, and compile.

Compiling on Linux

  • Copy the makefile into a file called Makefile
  • edit the Makefile to reflect the path to your SDK_ROOT/public/ directory
  • make

main.cpp

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Standalone utility to encrypt files with ice encryption, that doesn't
//			 depend on Steam.
//
// Author: Valve Software and Scott Loyd (scottloyd@gmail.com).
//			Tested and proofread by Me2.
// Depends on: Just needs public/IceKey.cpp to be compiled/linked with it
// $NoKeywords: $
//
//=============================================================================//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "IceKey.H"

// Globals
static bool g_Encrypt = true; //By default we encrypt

#define MAX_ICE_KEY 8
#define MAX_EXTENSION 16
static char g_ICEKey[MAX_ICE_KEY];
static char g_Extension[MAX_EXTENSION];

#ifdef WIN32
#define STRING_CMP stricmp
#else
#define STRING_CMP strcasecmp
#undef NULL
#define NULL 0
#endif


//----- Helpers -----
void Usage( void )
{
	printf( "Usage: ice <-d> <-x ext> [-k IceKey(8 byte)] [file]\n" );
	printf( "Default action: Encrypt. \n" );
	printf( "-d : Decrypt a file. \n" );
	printf( "-x : Extension to use as output. \n" );
	printf( "-k : You need to specify your 8 byte Ice Encryption Key. \n" );
	printf( "-h : Print the help menu, and stop.\n" );
}

void Exit(const char *msg)
{
	fprintf( stderr, msg );
	exit( 1 );
}

void SetExtension(char *dest, size_t length, const char *ext)
{
	//Start at the end till we hit a .
	//if we reach 0 without a .  just append the extension; one must not have existed.
	size_t mover = length;

	while( (*(dest + mover) != '.') && (mover > 0))
		mover--;

	if(mover == 0)
		strcat(dest,ext);
	else
	{
		strcpy(dest + mover,ext);
	}
}

/*
The entry point, see usage for I/O
*/
int main(int argc, char* argv[])
{
	if(argc < 2)
	{
		Usage();
		exit( 0 );
	}
	
	//By default we output .ctx
	strncpy( g_Extension, ".ctx",MAX_EXTENSION );
	memset(g_ICEKey,0,MAX_ICE_KEY);

	int i = 1;
	while( i < argc )
	{
		if( STRING_CMP( argv[i], "-h" ) == 0 )
		{
			Usage();
			exit( 0 );
		} 
		else if( STRING_CMP( argv[i], "-d" ) == 0 )
		{
			g_Encrypt = false;
		} 
		else if( STRING_CMP( argv[i], "-x" ) == 0 )
		{
			//Extension
			i++;

			if ( strlen( argv[i] ) > MAX_EXTENSION )
			{
				Exit("Your Extension is too big.\n");
			}

			strncpy( g_Extension, argv[i], MAX_EXTENSION );
		}
		else if( STRING_CMP( argv[i], "-k" ) == 0 )
		{
			//Key
			i++;

			if ( strlen( argv[i] ) != MAX_ICE_KEY )
			{
				Exit("Your ICE key needs to be 8 characters long.\n");
			}

			strncpy( g_ICEKey, argv[i], MAX_ICE_KEY );
		}
		else 
		{
			break;
		}
		i++;
	}

	if(g_ICEKey[0] == '\0') {
		Exit("You need to specify a key.\n");
	}
	//Parse files starting from current arg position
	if(argv[i] == NULL && (strlen(argv[i]) < 1))
		Exit("Was not about to find a file to parse\n");

	//Open allocate/read a file into memory
	FILE *pFile;
	pFile = fopen (argv[i], "rb");
	if(! pFile)
		Exit("Failed to open input file\n");

	long lFileSize; //Size of input file
	unsigned char *pBuff; //Holds the input file contents
	unsigned char *pOutBuff; //Holds the output goodies

	// obtain file size.
	fseek (pFile , 0 , SEEK_END);
	lFileSize= ftell (pFile);
	rewind (pFile);

	// allocate memory to contain the whole file.
	pBuff = (unsigned char*) malloc (lFileSize);
	pOutBuff = (unsigned char*) malloc (lFileSize);

	if (pBuff == NULL || pOutBuff == NULL)
	{
		fclose(pFile);
		Exit("Could not allocate buffer\n");;
	}

	// copy the file into the buffer.
	fread (pBuff,1,lFileSize,pFile);
	
	//clean the output buffer
	memset(pOutBuff,NULL,lFileSize);

	fclose(pFile);

	//Lets start the ice goodies!
	IceKey ice( 0 ); // level 0 = 64bit key
	ice.set( (unsigned char*) g_ICEKey ); // set key

	int blockSize = ice.blockSize();

	unsigned char *p1 = pBuff;
	unsigned char *p2 = pOutBuff;

	// encrypt data in 8 byte blocks
	int bytesLeft = lFileSize;

	while ( bytesLeft >= blockSize )
	{
		if ( g_Encrypt )
			ice.encrypt( p1, p2 );
		else
			ice.decrypt( p1, p2 );

		bytesLeft -= blockSize;
		p1+=blockSize;
		p2+=blockSize;
	}

	//The end chunk doesn't get an encryption?  that sux...
	memcpy( p2, p1, bytesLeft );

	size_t outLength = strlen(argv[i]) + MAX_EXTENSION + 1;
	char *pOutPath = (char *)malloc(outLength);
	strncpy(pOutPath,argv[i],outLength);

	SetExtension(pOutPath, outLength, g_Extension);

	pFile = fopen (pOutPath , "wb");
	if(pFile == NULL)
	{
		fprintf( stderr, "Was not able to open output file for writing.\n" );
		goto dealloc;
	}

	fwrite (pOutBuff , 1 , lFileSize , pFile);
	fclose (pFile);

dealloc:
	free(pBuff);
	free(pOutBuff);
	free(pOutPath);
}

Linux Makefile

#Simple Makefile for compiling on Linux
CPP = g++
PUBLIC=../../public

ice:
	${CPP} -o $@ main.cpp ${PUBLIC}/IceKey.cpp -I${PUBLIC}

clean:
	-rm -f ice

(Optional) Perl Script to make life easier

I use Env. Variables in all my scripts because of multiple developers, so you can either hardcode the variables, or set the env. variables on your system (see msdn docs. for that). Also, to take this even further, on my system I created a new MSVC project, then changed it to a utility project (leaving me with just build events); I then called the perl script as my post-build and MSVC now does everything for me in my build process.

#!/usr/bin/perl
# easy script that compiles our scripts folder and then moves them to our mod directory!

use warnings;
use strict;

use File::Copy;


our $outExt = ".ctx";

our $baseOutput = $ENV{'MOD_CONTENT'};
die("Could not find MOD_CONTENT envirornment variable.\n") if !$baseOutput;
our $outputDir = $baseOutput."\\scripts";

our $inputDir = $ENV{'CODE_SCRIPTS'};
die("Could not find CODE_SCRIPTS envirornment variable.\n") if !$inputDir;

our $iceKey = $ENV{'ICE_KEY'};
die("Could not find ICE_KEY envirornment variable.\n") if !$iceKey;


our $devToolPath = $ENV{'CODE_DEVTOOLS'};
die("Could not find CODE_DEVTOOLS envirornment variable.\n") if !$devToolPath;

printf(" ** Encrypting scripts and copying them into your mod ** \n");

my $command = "$devToolPath\\ice -x $outExt -k $iceKey ";

opendir DH, $inputDir or die "Could not open code-scripts directory\n";

	while ($_ = readdir(DH))
	{
		# we don't want to process . or .. directory holders.
		next if $_ eq ".";
		next if $_ eq "..";
		next if -d $_;
		next if $_ !~ m/.txt$/;
		
		my $inFile = $inputDir."\\".$_;
		system($command.$inFile);
		
		#printf "Command: ".$command.$inFile."\n";
		
		#Get a filename/path without the extension, add the extension to the end.
		my $outFile = $outputDir."\\".$_;
		$outFile =~ s/(.*).txt$/$1.ctx/;
		$inFile =~ s/(.*).txt$/$1.ctx/;
		
		#printf "InFile: ".$inFile."\n";
		#printf "OutFile: ".$outFile."\n";
		move($inFile,$outFile);
	}
closedir DH;

See also