windows-nt/Source/XPSP1/NT/base/ntsetup/complnce/pidinit/pidinit.c

280 lines
6.8 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
#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;
}