You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
280 lines
7.1 KiB
280 lines
7.1 KiB
#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;
|
|
}
|