📄 installer.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: Installer.c,v 1.7 2002/10/19 00:18:58 wjb Exp $
____________________________________________________________________________*/
#include <windows.h>
#include "PGPadmin.h"
#include "Utils.h"
#include <stdio.h>
#include <io.h>
#include <direct.h>
#include <shlwapi.h>
#include "PGPadminRes.h"
#include "pgpClientLib.h"
#include "pgpSEA.h"
#include "pgpSDAcreate.h"
#include "progress.h"
HINSTANCE g_hinst;
#define DEL_KEYS 1
#define DEL_TOOLS 2
#define DEL_LOGIN 4
#define DEL_NET 8
#define DEL_VPN 16
#define DEL_FIRE 32
#define DEL_DISK 64
#define DEL_OUTLOOK 128
#define DEL_OE 256
#define DEL_EUDORA 512
#define DEL_ICQ 1024
#define DEL_LOTUS 2048
#define DEL_DOCS 4096
#define DEL_CONTEXT 8192
#define DEL_GROUPWISE 16384
static char *g_InstallArray[][20]=
{
//PGP Keys
{"pgpkeys.exe",
NULL},
//PGP Tools
{"pgpmail.exe",
"pgplog.exe",
NULL},
//PGP Login Integration
{"pgpnpi.dll",
"pgpgina.dll",
NULL},
//PGPnet
{"pgpnet.vxd",
"pgpnet.sys",
"pgpnetwin2k.sys",
"pgprebind.inf",
"pgpnet.chm",
"pgpnet.exe",
"setadapter.exe",
"pgpnet.inf",
"pgpnet_m.inf",
NULL},
//PGPvpn
{"pgpcfg.vxd",
"pgpcfg.sys",
"PGPcfgwin2k.sys",
"pgpcfg2k.inf",
NULL},
//PGPfire
{"pgptdi.vxd",
"pgptdi.sys",
NULL},
//PGPdisk Volume Security
{"pgpdiskengine.dll",
"pgpdiskih.dll",
"pgpdiskui.dll",
"pgpdisk.pdr",
"pgpdisk.sys",
"pgpdiskwin2k.sys",
"pgpdisk.exe",
NULL},
//PGP Plugin for Microsoft Outlook
{"pgpexch.dll",
NULL},
//PGP Plugin for Microsoft Outlook Express
{"pgpoe.dll",
NULL},
//PGP Plugin for Qualcomm Eudora
{"eudoraplugin.dll",
"eudorapluginv4.dll",
NULL},
//PGP Plugin for ICQ
{"pgpicq.dll",
NULL},
//PGP Plugin for Lotus Notes
{"ndbpgp.dll",
NULL},
//PGP Documentation
{"pgpwinusersguide.pdf",
"introtocrypto.pdf",
"readme.htm",
NULL},
//PGP context menu
{"pgpmn.dll",
NULL},
//PGP Plugin for Grouwise
{"pgpgw.dll",
NULL}
};
PGPError SDADecryptFiles(SDAHEADER *SDAHeader,
PGPUInt32 *ExpandedKey,
FILELIST **fl,
char *szInFileName,
char *szPrefixPath,
SDACREATECALLBACK UserProc,void *pUserValue);
static void sCreateInstaller(HWND hwndMain, pgpConfigInfo *pConfig);
UINT FileListFromFile(FILELIST **filelist,char *filename,BOOL *UserCancel);
void RemoveFiles(FILELIST *fl);
// find if iPstr2 is in iPstr1
// case doesn't matter
// return is same as strstr
static char *mystrstri(char *iPstr1, char *iPstr2)
{
int i;
int Len = strlen(iPstr2);
int MaxLen = strlen(iPstr1)-Len;
for(i=0; i<=MaxLen; i++)
{
if(!strnicmp(iPstr1+i, iPstr2, Len))
break;
}
if(i>MaxLen)
return NULL;
return (iPstr1+i);
}
FILELIST *DeleteFLEntry(FILELIST *flin,char *szFile)
{
FILELIST *flout,*flprev,*freeatlast;
DWORD retval;
flout=flin;
flprev=NULL;
while(flin!=NULL)
{
if(mystrstri(flin->name,szFile)!=NULL)
{
// We found it!
freeatlast=flin;
if(flprev==NULL)
{
flout=flin->next;
}
else
{
flprev->next=flin->next;
}
// Advance
flin=flin->next;
// Erase file and entry
if(freeatlast->IsDirectory)
{
retval=_rmdir(freeatlast->name);
}
else
{
retval=_unlink(freeatlast->name);
}
memset(freeatlast->name,0x00,strlen(freeatlast->name));
free(freeatlast->name);
free(freeatlast);
}
else
{
// Update previous
flprev=flin;
//Advance
flin=flin->next;
}
}
return flout;
}
FILELIST *DeleteComponents(FILELIST *flin,DWORD dwDelete)
{
int compindex;
int fileindex;
FILELIST *flout;
flout=flin;
for(compindex=0;compindex<32;compindex++)
{
if((dwDelete&1)==1)
{
fileindex=0;
while(g_InstallArray[compindex][fileindex]!=NULL)
{
flout=DeleteFLEntry(flout,
g_InstallArray[compindex][fileindex]);
fileindex++;
}
}
dwDelete=dwDelete>>1;
}
return flout;
}
#define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + \
((PIMAGE_DOS_HEADER)a)->e_lfanew))
FILELIST *ReverseFileList(FILELIST *flin)
{
FILELIST *flnext,*flout;
flout=NULL;
while(flin!=NULL)
{
flnext=flin->next;
flin->next=flout;
flout=flin;
flin=flnext;
}
return (flout);
}
PGPError SEAGetTempPath(char *szPrefixPath)
{
char HexString[100];
int ret_val;
// Note that GetTempPath returns a path with a backslash
if(GetTempPath(MAX_PATH,szPrefixPath ) == 0)
{
return kPGPError_UnknownError;
}
srand( (unsigned)time( NULL ) );
sprintf(HexString,"%x",rand()*rand());
HexString[5]=0; // Truncate at length 5
strcat(szPrefixPath,"PGP");
strcat(szPrefixPath,HexString);
strcat(szPrefixPath,"\\");
ret_val=_mkdir(szPrefixPath);
if(ret_val!=0)
{
return kPGPError_UnknownError;
}
return kPGPError_NoErr;
}
BOOL WriteAdminFile(HWND hwnd,
char *filename,
char *prefpath,
FILELIST **p_fl,
char *buf,
DWORD size)
{
FILE *fout;
char name[MAX_PATH+1];
if(buf==NULL)
return TRUE;
strcpy(name,prefpath);
strcat(name,filename);
fout=fopen(name,"wb");
if(fout==0)
{
MessageBox(hwnd,"Can't create file",
name,
MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
return FALSE;
}
else
{
fwrite(buf,1,size,fout);
fclose(fout);
// Remember file so we can delete it later
FileListFromFile(p_fl,name,NULL);
}
return TRUE;
}
typedef struct
{
HWND hwndWorking;
DWORD dwDelete;
char *szInFile;
char *szOutFile;
char *ClientBuffer;
DWORD ClientSize;
char *NetBuffer;
DWORD NetSize;
char *SetupBuffer;
DWORD SetupSize;
char *KeysBuffer;
DWORD KeysSize;
} ADMINSEAWORK;
/* Generic event handler */
PGPError
SDAEvents(
PGPContextRef context,
SDAEvent *event,
PGPUserValue userValue
)
{
ADMINSEAWORK *AdminSEAWork;
(void) context;
AdminSEAWork=(ADMINSEAWORK *)userValue;
switch( event->type )
{
case kSDAEvent_ErrorEvent:
{
SDAEventErrorData *d = &event->data.errorData;
MessageBox(AdminSEAWork->hwndWorking,
"Error encoding file",d->fileName,
MB_OK|MB_SETFOREGROUND|MB_ICONSTOP);
break;
}
case kSDAEvent_ProgressEvent:
{
SDAEventProgressData *d = &event->data.progressData;
if(d->bytesTotal!=0)
{
return PGPscProgressSetBar(AdminSEAWork->hwndWorking,
(DWORD)(d->bytesWritten*100/d->bytesTotal),FALSE);
}
break;
}
case kSDAEvent_NewFileEvent:
{
SDAEventNewFileData *d = &event->data.newfileData;
PGPscProgressSetNewFilename(AdminSEAWork->hwndWorking,"In '%s'",
d->fileName,FALSE);
break;
}
case kSDAEvent_AskFileEvent:
{
SDAEventAskFileData *d = &event->data.askfileData;
strcpy(d->outName,d->inName);
break;
}
case kSDAEvent_GetSDARandomBitsEvent:
{
SDAEventGetSDARandomBitsData *d = &event->data.randomData;
break;
}
case kSDAEvent_WriteSDAStubEvent:
{
DWORD dwStubSize;
HRSRC hRCStub;
HGLOBAL hGBStub;
char *pStubData;
HMODULE hModule;
SDAEventWriteSDAStubData *d = &event->data.stubData;
hModule=GetModuleHandle(NULL);
hRCStub=FindResource(hModule,
MAKEINTRESOURCE(IDR_SEASTUB),
RT_RCDATA);
dwStubSize=SizeofResource(hModule,hRCStub);
hGBStub=LoadResource(hModule,hRCStub);
pStubData=(char *)LockResource(hGBStub);
// Sanity checking here for resource munging
if(!((*(USHORT *)pStubData == IMAGE_DOS_SIGNATURE) &&
(*(DWORD *)NTSIGNATURE (pStubData) == IMAGE_NT_SIGNATURE)))
{
MessageBox(AdminSEAWork->hwndWorking,
"Error writing stub file","PGPadmin",
MB_OK|MB_SETFOREGROUND|MB_ICONSTOP);
return kPGPError_UserAbort;
}
// Copy SDA.exe prefix executable into SDA file and
// set header offset so we can find data again.
// Write out stub to disk from resources
fwrite(pStubData,1,dwStubSize,d->fOutput);
UnlockResource(hGBStub);
FreeResource(hGBStub);
break;
}
default:
break;
}
return kPGPError_NoErr;
}
PGPError RebuildInstallerStub(HWND hwndWorking,void *pUserValue)
{
SDAHEADER SDAHeader;
FILE *fin;
FILELIST *fl;
PGPError err;
ADMINSEAWORK *AdminSEAWork;
char szPrefixPath[MAX_PATH+1];
AdminSEAWork=(ADMINSEAWORK *)pUserValue;
AdminSEAWork->hwndWorking=hwndWorking;
fin=fopen(AdminSEAWork->szInFile,"rb");
fseek(fin, -(int)(sizeof(SDAHEADER)), SEEK_END);
fread(&SDAHeader,1,sizeof(SDAHEADER),fin);
fclose(fin);
if(memcmp(SDAHeader.szPGPSDA,"PGPSEA",6)!=0)
{
MessageBox(AdminSEAWork->hwndWorking,
"Not a valid SEA",
"PGPadmin",
MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
return kPGPError_UserAbort;
}
err=SEAGetTempPath(szPrefixPath);
if(err!=kPGPError_NoErr)
return err;
fl=NULL;
// Keep track of it so we can delete it later
FileListFromFile(&fl,szPrefixPath,NULL);
fl->IsDirectory=TRUE;
err=SDADecryptFiles(&SDAHeader,
NULL,
&fl,
AdminSEAWork->szInFile,
szPrefixPath,
SDAEvents,AdminSEAWork);
if(IsntPGPError(err))
{
// ********************************************
// Now is the time to delete our old files
// ********************************************
fl=DeleteComponents(fl,AdminSEAWork->dwDelete);
if(AdminSEAWork->ClientBuffer!=NULL)
fl=DeleteFLEntry(fl,"Disk1\\PGPPrefs.txt");
if(AdminSEAWork->NetBuffer!=NULL)
fl=DeleteFLEntry(fl,"Disk1\\PGPnetPrefs.txt");
if(AdminSEAWork->SetupBuffer!=NULL)
fl=DeleteFLEntry(fl,"Disk1\\setup.ini");
if(AdminSEAWork->KeysBuffer!=NULL)
fl=DeleteFLEntry(fl,"Disk1\\DefaultKeys.asc");
WriteAdminFile(AdminSEAWork->hwndWorking,
"Disk1\\PGPPrefs.txt",
szPrefixPath,
&fl,
AdminSEAWork->ClientBuffer,
AdminSEAWork->ClientSize);
WriteAdminFile(AdminSEAWork->hwndWorking,
"Disk1\\PGPnetPrefs.txt",
szPrefixPath,
&fl,
AdminSEAWork->NetBuffer,
AdminSEAWork->NetSize);
WriteAdminFile(AdminSEAWork->hwndWorking,
"Disk1\\setup.ini",
szPrefixPath,
&fl,
AdminSEAWork->SetupBuffer,
AdminSEAWork->SetupSize);
WriteAdminFile(AdminSEAWork->hwndWorking,
"Disk1\\DefaultKeys.asc",
szPrefixPath,
&fl,
AdminSEAWork->KeysBuffer,
AdminSEAWork->KeysSize);
// Reverse the list to re-encode
fl=ReverseFileList(fl);
// Re-encode to same file
err=SDACreate(NULL,fl,
AdminSEAWork->szOutFile,NULL,
SDAEvents,AdminSEAWork,0);
// Reverse the list to delete
fl=ReverseFileList(fl);
}
RemoveFiles(fl);
return err;
}
BOOL RebuildInstaller(HWND hwnd,
DWORD dwDelete,
char *szInFile,
char *szOutFile,
char *ClientBuffer,
DWORD ClientSize,
char *NetBuffer,
DWORD NetSize,
char *SetupBuffer,
DWORD SetupSize,
char *KeysBuffer,
DWORD KeysSize)
{
ADMINSEAWORK AdminSEAWork;
g_hinst=g_hInstance;
memset(&AdminSEAWork,0x00,sizeof(ADMINSEAWORK));
AdminSEAWork.szInFile=szInFile;
AdminSEAWork.szOutFile=szOutFile;
AdminSEAWork.ClientBuffer=ClientBuffer;
AdminSEAWork.ClientSize=ClientSize;
AdminSEAWork.NetBuffer=NetBuffer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -