|
|
#include <windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <direct.h>
#include "crc-32.h"
// length of the string we expect with the /m option
#define RPC_LENGTH 5
// (max) length of the _SUFFIX strings
#define RPC_SUFFIX_LENGTH 3
#define STEPUPFLAG TEXT("_STEPUP_")
#define BASE 'a'
#define DEFAULT_RPC "00000"
#define SELECT_SUFFIX "270"
#define MSDN_SUFFIX "335"
#define RETAIL_SUFFIX "000"
#define OEM_SUFFIX "OEM"
DWORD WINAPI CRC_32(LPBYTE pb, DWORD cb) {
// CRC-32 algorithm used in PKZip, AUTODIN II, Ethernet, and FDDI
// but xor out (xorot) has been changed from 0xFFFFFFFF to 0 so
// we can store the CRC at the end of the block and expect 0 to be
// the value of the CRC of the resulting block (including the stored
// CRC).
cm_t cmt = { 32, // cm_width Parameter: Width in bits [8,32].
0x04C11DB7, // cm_poly Parameter: The algorithm's polynomial.
0xFFFFFFFF, // cm_init Parameter: Initial register value.
TRUE, // cm_refin Parameter: Reflect input bytes?
TRUE, // cm_refot Parameter: Reflect output CRC?
0, // cm_xorot Parameter: XOR this to output CRC.
0 // cm_reg Context: Context during execution.
};
// Documented test case for CRC-32:
// Checking "123456789" should return 0xCBF43926
cm_ini(&cmt); cm_blk(&cmt, pb, cb);
return cm_crc(&cmt); }
VOID GiveUsage() { _tprintf(TEXT("pidinit -d <flags> -g <outputname> -m <mpccode> -s[smro] -z -h -?\n")); _tprintf(TEXT("writes a signature to <outputname> based on <flags>\n")); _tprintf(TEXT("-s (SiteType) s (select) m (msdn) r (retail) o (oem)\n")); _tprintf(TEXT("-z (decode)\n")); _tprintf(TEXT("-m <mpccode> : mpccode is a 5 digit number\n")); _tprintf(TEXT("-h or -? this message\n")); }
int _cdecl main( int argc, char *argvA[] ) /*++
Routine Description:
Entry point to the setup program
Arguments:
argc - Number of args. argvA - the commandline arguments.
Return Value:
--*/ { LPTSTR *argv; int argcount = 0; long rslt;
char data[10+4+1] = {0}; char buf[1000] = {0};
DWORD value, crcvalue,outval;//,tmp;
BOOL StepUp = FALSE; BOOL decode = FALSE; BOOL bMpc = FALSE;
LPSTR SiteSuffix[] = { SELECT_SUFFIX, MSDN_SUFFIX, RETAIL_SUFFIX, OEM_SUFFIX };
typedef enum SiteType { Select = 0, Msdn, Retail, Oem, } ;
enum SiteType st = Select; int i, randval;
char *outname = NULL; char path[MAX_PATH]; char *mpcName = NULL; char tString[RPC_LENGTH+RPC_SUFFIX_LENGTH+1]; // do commandline stuff
#ifdef UNICODE
argv = CommandLineToArgvW( GetCommandLine(), &argc ); #else
argv = argvA; #endif
// check for commandline switches
for (argcount=0; argcount<argc; argcount++) { if ((argv[argcount][0] == L'/') || (argv[argcount][0] == L'-')) { switch (towlower(argv[argcount][1])) { case 'd': if (lstrcmpi(&argv[argcount][2],STEPUPFLAG ) == 0) { StepUp = TRUE; } break; case 'g': outname = argv[argcount + 1]; break; case 's': switch (towlower(argv[argcount+1][0])) { case 's': st = Select; break; case 'm': st = Msdn; break; case 'r': st = Retail; break; case 'o': st = Oem; break; default: st = Select; break; } break;
case 'z': decode = TRUE; break;
case 'm': bMpc = TRUE; mpcName = argv[argcount + 1]; break;
case 'h': case '?': GiveUsage(); return 1; break; default: break; } } }
if (!outname) { _tprintf(TEXT("you must supply a filename\n")); GiveUsage(); return 1; }
//
// the decode section is really only for testing
//
if (decode) { _getcwd ( path, MAX_PATH ); sprintf( path, "%s\\%s", path, outname ); GetPrivateProfileStruct( "Pid", "ExtraData", data, 14, path );
crcvalue = CRC_32( (LPBYTE)data, 10 ); memcpy(&outval,&data[10],sizeof(DWORD)); if (crcvalue != outval ) { printf("CRC doesn't match %x %x!\n", crcvalue, outval); return 1; }
if ((data[3]-BASE)%2) { if ((data[5]-BASE)%2) { printf("stepup mode\n"); return 1; } else { printf("bogus!\n"); return -1; } } else if ((data[5]-BASE)%2) { printf("bogus!\n"); return -1; } else { printf("full retail mode\n"); return 1; }
} srand( (unsigned)time( NULL ) ); for (i=0;i< 10; i++ ) { randval = rand() ; data[i] = BASE + (randval % 26); }
if (StepUp) { if (!((data[3]- BASE)%2)) { data[3] = data[3] + 1; }
if (!((data[5]- BASE )%2)) { data[5] = data[5] + 1; } } else { if ((data[3]- BASE)%2) { data[3] = data[3] + 1; } if ((data[5]- BASE)%2) { data[5] = data[5] + 1; } }
//printf( "data : %s\n" , data );
crcvalue = CRC_32( (LPBYTE)data, strlen(data) ); memcpy(&data[10],&crcvalue,4); _getcwd ( path, MAX_PATH ); sprintf( path, "%s\\%s", path, outname );
WritePrivateProfileStruct( "Pid", "ExtraData", data, 14, path );
//
// Allow another to specify the RPC code
//
if (bMpc){ lstrcpyn(tString,mpcName,RPC_LENGTH+1); } else { lstrcpyn(tString,DEFAULT_RPC,RPC_LENGTH+1); } lstrcpy(&tString[RPC_LENGTH],SiteSuffix[st]); WritePrivateProfileString( "Pid", "Pid", tString, path );
return 1; }
|