📄 decodestub.c
字号:
/*__________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: DecodeStub.c,v 1.18 2002/08/06 20:10:28 dallen Exp $
__________________________________________________________________________*/
#include "DecodeStub.h"
HINSTANCE g_hinst;
/* Generic event handler */
PGPError
SDAEvents(
PGPContextRef context,
SDAEvent *event,
PGPUserValue userValue
)
{
SDAWORK *sdaw;
(void) context;
sdaw = (SDAWORK *)userValue;
if(PGPscProgressGetCancel(sdaw->hwndWorking))
{
return kPGPError_UserAbort;
}
switch( event->type )
{
case kSDAEvent_ErrorEvent:
{
SDAEventErrorData *d = &event->data.errorData;
if(d->err==kPGPError_BufferTooSmall)
{
MessageBox(sdaw->hwndWorking,
"Filename exceeds maximum length.\n"
"Try decrypting to the root of a volume.",d->fileName,
MB_OK|MB_SETFOREGROUND|MB_ICONSTOP);
}
else
{
MessageBox(sdaw->hwndWorking,
"Error decoding file",d->fileName,
MB_OK|MB_SETFOREGROUND|MB_ICONSTOP);
}
break;
}
case kSDAEvent_ProgressEvent:
{
SDAEventProgressData *d = &event->data.progressData;
if(d->bytesTotal!=0)
{
return PGPscProgressSetBar(sdaw->hwndWorking,
(DWORD)(d->bytesWritten*100/d->bytesTotal),FALSE);
}
break;
}
case kSDAEvent_NewFileEvent:
{
#ifndef IS_SEA
SDAEventNewFileData *d = &event->data.newfileData;
PGPscProgressSetNewFilename(sdaw->hwndWorking,"To '%s'",
d->fileName,FALSE);
#ifdef PGPREADER
if(sdaw->EBIZHeader && ++sdaw->dwFileNum == sdaw->EBIZHeader->autoExecNum)
{
strcpy(sdaw->szAutoRun, d->fileName);
}
#endif /* PGPREADER */
#endif // IS_SEA
break;
}
case kSDAEvent_AskFileEvent:
{
SDAEventAskFileData *d = &event->data.askfileData;
#ifndef IS_SEA
char Message[256];
LoadString (g_hinst, IDS_SELECTFILENAME, Message, sizeof(Message));
if(SaveOutputFile(sdaw->hwndWorking,
Message,
d->inName,
d->outName))
{
// User canceled
return(kPGPError_UserAbort);
}
#ifdef PGPREADER
if(sdaw->EBIZHeader && sdaw->dwFileNum == sdaw->EBIZHeader->autoExecNum)
strcpy(sdaw->szAutoRun, d->outName);
#endif /* PGPREADER */
#else
strcpy(d->outName,d->inName);
#endif // IS_SEA
break;
}
case kSDAEvent_GetSDARandomBitsEvent:
{
break;
}
case kSDAEvent_WriteSDAStubEvent:
{
break;
}
default:
break;
}
return kPGPError_NoErr;
}
// find if iPstr2 is in iPstr1
// case doesn't matter
// return is same as strstr
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);
}
#ifndef IS_SEA
#ifdef PGPREADER
static
PGPInt32
sCalculateEBIZHeaderSize(EBIZHEADER *pEBIZHeader)
{
PGPInt32 size = sizeof(pEBIZHeader->autoExecNum);
size += sizeof(pEBIZHeader->bEncryptedToADK);
size += sizeof(pEBIZHeader->encryptedBlock);
size += sizeof(pEBIZHeader->MajorVersion);
size += sizeof(pEBIZHeader->MinorVersion);
size += sizeof(pEBIZHeader->size);
size += sizeof(pEBIZHeader->szPGPEBIZ);
return size;
}
static
void
sReadEBIZHeader(EBIZHEADER *pEBIZHeader, FILE *fp)
{
fread(&pEBIZHeader->autoExecNum, sizeof(pEBIZHeader->autoExecNum), 1, fp);
fread(pEBIZHeader->encryptedBlock, sizeof(pEBIZHeader->encryptedBlock), 1, fp);
fread(&pEBIZHeader->size, sizeof(pEBIZHeader->size), 1, fp);
fread(&pEBIZHeader->bEncryptedToADK, sizeof(pEBIZHeader->bEncryptedToADK), 1, fp);
fread(&pEBIZHeader->MinorVersion, sizeof(pEBIZHeader->MinorVersion), 1, fp);
fread(&pEBIZHeader->MajorVersion, sizeof(pEBIZHeader->MajorVersion), 1, fp);
fread(pEBIZHeader->szPGPEBIZ, sizeof(pEBIZHeader->szPGPEBIZ), 1, fp);
}
#endif /* PGPREADER */
static
PGPInt32
sCalculateHeaderSize(SDAHEADER *pSDAHeader)
{
PGPInt32 size = sizeof(pSDAHeader->szPGPSDA);
size += sizeof(pSDAHeader->offset);
size += sizeof(pSDAHeader->CompLength);
size += sizeof(pSDAHeader->NumFiles);
#ifdef IS_SEA
size += sizeof(pSDAHeader->Flags);
#else
size += sizeof(pSDAHeader->Salt);
size += sizeof(pSDAHeader->hashReps);
size += sizeof(pSDAHeader->CheckBytes);
#endif
return size;
}
static
void
sReadHeader(SDAHEADER *pSDAHeader, FILE *fp)
{
fread(pSDAHeader->szPGPSDA, sizeof(pSDAHeader->szPGPSDA), 1, fp);
fread(&pSDAHeader->offset, sizeof(pSDAHeader->offset), 1, fp);
fread(&pSDAHeader->CompLength, sizeof(pSDAHeader->CompLength), 1, fp);
fread(&pSDAHeader->NumFiles, sizeof(pSDAHeader->NumFiles), 1, fp);
#ifdef IS_SEA
fread(&pSDAHeader->Flags, sizeof(pSDAHeader->Flags), 1, fp);
#else
fread(&pSDAHeader->Salt, sizeof(pSDAHeader->Salt), 1, fp);
fread(&pSDAHeader->hashReps, sizeof(pSDAHeader->hashReps), 1, fp);
fread(pSDAHeader->CheckBytes, sizeof(pSDAHeader->CheckBytes), 1, fp);
#endif
}
#endif /* !IS_SEA */
PGPError SDADecryptStub(HWND hwndWorking,void *pUserValue)
{
HWND hwnd;
SDAHEADER SDAHeader;
#ifdef PGPREADER
EBIZHEADER EBIZHeader;
#endif /* PGPREADER */
PGPUInt32 *ExpandedKey;
FILE *fin;
char filename[MAX_PATH+1];
char szPrefixPath[MAX_PATH+1];
char Caption[100];
char Message[100];
SDAWORK *SDAWork;
FILELIST *fl;
PGPError err;
SDAWork=(SDAWORK *)pUserValue;
SDAWork->hwndWorking=hwndWorking;
fl=NULL;
LoadString (g_hinst, IDS_PGPERROR, Caption, sizeof(Caption));
ExpandedKey=NULL;
hwnd=SDAWork->hwndWorking;
GetModuleFileName(NULL, filename, MAX_PATH);
do
{
fin=fopen(filename,"rb");
if(fin==0)
{
LoadString (g_hinst, IDS_COULDNOTOPENFILE, Message, sizeof(Message));
MessageBox(hwnd,Message,
filename,
MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
return kPGPError_UserAbort;
}
fflush(fin);
#ifndef IS_SEA
/* Calculate size of SDAHeader */
#ifdef PGPREADER
_lseeki64(fileno(fin), -(_int64)(sCalculateHeaderSize(&SDAHeader) + sCalculateEBIZHeaderSize(&EBIZHeader)), SEEK_END);
sReadEBIZHeader(&EBIZHeader, fin);
sReadHeader(&SDAHeader, fin);
#else /* !PGPREADER */
_lseeki64(fileno(fin), -(_int64)(sCalculateHeaderSize(&SDAHeader)), SEEK_END);
sReadHeader(&SDAHeader, fin);
#endif /* PGPREADER */
#else /* IS_SEA */
_lseeki64(fileno(fin), -((_int64)(sizeof(SDAHEADER))), SEEK_END);
// fseek fails on calls to end of file, but seems ok to seek from
// beginning over stub...
// fseek(fin, -(int)(sizeof(SDAHEADER)), SEEK_END);
fread(&SDAHeader,1,sizeof(SDAHEADER),fin);
#endif /* !IS_SEA */
fclose(fin);
#ifndef IS_SEA // This is for SDA only
#ifdef PGPREADER
if(memcmp(EBIZHeader.szPGPEBIZ, PGPEBIZ, strlen(PGPEBIZ)) == 0)
{
/* Check for additional features */
SDAWork->EBIZHeader = &EBIZHeader;
}
#endif /* PGPREADER */
if((SDAHeader.offset==0)&&(memcmp(SDAHeader.szPGPSDA,"PGPSDA",6)==0))
{
// An SDA with a zero offset? This is a helper application
char *szDecoder;
fin=0;
szDecoder=mystrstri(filename,".decoder.sda.exe");
if(szDecoder==NULL)
{
LoadString (g_hinst, IDS_NOTDECODER, Message, sizeof(Message));
MessageBox(hwnd,Message,
Caption,
MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
return kPGPError_UserAbort;
}
// Go get the real one
strcpy(szDecoder,".sda.exe");
}
#endif // !IS_SEA
} while(fin==0);
#ifndef IS_SEA
if(memcmp(SDAHeader.szPGPSDA,"PGPSDA",6)!=0)
{
LoadString (g_hinst, IDS_NOTVALIDSDA, Message, sizeof(Message));
MessageBox(hwnd,Message,
Caption,
MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
return kPGPError_UserAbort;
}
GetPrefixPath(szPrefixPath);
// Fetch the passphrase from the user
err=SDAPassphraseDialog(SDAWork->hwndWorking,
&SDAHeader,&ExpandedKey,szPrefixPath);
if(err!=kPGPError_NoErr)
return err;
#else
if(memcmp(SDAHeader.szPGPSDA,"PGPSEA",6)!=0)
{
LoadString (g_hinst, IDS_NOTVALIDSEA, Message, sizeof(Message));
MessageBox(hwnd,Message,
Caption,
MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
return kPGPError_UserAbort;
}
err=SEAGetTempPath(szPrefixPath);
if(err!=kPGPError_NoErr)
return err;
//#endif // IS_SEA
// Keep track of it so we can delete it later
FileListFromFile(&fl,szPrefixPath,NULL);
fl->IsDirectory=TRUE;
#endif // IS_SEA
err=SDADecryptFiles(&SDAHeader,
ExpandedKey,
&fl,
filename,
szPrefixPath,
SDAEvents,pUserValue);
#ifndef IS_SEA
if(IsPGPError(err))
{
RemoveFiles(fl);
}
memset(ExpandedKey,0x00,sizeof(PGPUInt32)*32);
free(ExpandedKey);
#ifdef PGPREADER
if(SDAWork->szAutoRun[0] != '\0')
{
/* Launch this bad boy */
char szBuffer[MAX_PATH + 1] = {'\0'};
sprintf(szBuffer, "Warning! Archive contained a file that was marked for AutoRun. "
"Never run software you do not trust! "
"Do you wish to AutoRun %s.", SDAWork->szAutoRun);
if(MessageBox(hwndWorking, szBuffer, "Self Decrypting Archive - AutoRun", MB_ICONWARNING | MB_ICONQUESTION | MB_YESNO) == IDYES)
{
if(WinExec(SDAWork->szAutoRun, SW_SHOWDEFAULT) <= 31)
{
err = kPGPError_FileOpFailed;
}
}
}
#endif /* PGPREADER */
#else
if(IsntPGPError(err))
{
SEACreateAndExec(filename,
hwnd,
&SDAHeader,
szPrefixPath,
&fl);
}
RemoveFiles(fl);
#endif // IS_SEA
return err;
}
#ifdef IS_SEA
PGPBoolean IsSEASilent()
{
SDAHEADER SDAHeader;
PGPUInt32 *ExpandedKey;
FILE *fin;
char filename[MAX_PATH+1];
FILELIST *fl;
fl=NULL;
ExpandedKey=NULL;
GetModuleFileName(NULL, filename, MAX_PATH);
do
{
fin=fopen(filename,"rb");
if(fin==0)
{
return 0;
}
fflush(fin);
_lseeki64(fileno(fin), -((_int64)(sizeof(SDAHEADER))), SEEK_END);
fread(&SDAHeader,1,sizeof(SDAHEADER),fin);
fclose(fin);
} while(fin==0);
if(memcmp(SDAHeader.szPGPSDA,"PGPSEA",6)!=0)
{
return 0;
}
else
{
if (SDAHeader.Flags & SEA_SILENT)
return 1;
else
return 0;
}
}
#endif // IS_SEA
PGPError SDA(HWND hwnd)
{
SDAWORK SDAWork;
PGPError err;
PGPBoolean bSilent = FALSE;
memset(&SDAWork,0x00,sizeof(SDAWORK));
#ifdef IS_SEA
bSilent = IsSEASilent();
#endif // IS_SEA
if(bSilent)
{
err=SDADecryptStub(hwnd,&SDAWork);
}
else
{
err=PGPscProgressDialog(hwnd,SDADecryptStub,&SDAWork,
0,NULL,
NULL,NULL,0);
}
return err;
}
LRESULT CALLBACK HiddenWndProc (HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam)
{
RECT rc;
switch (iMsg)
{
case WM_CREATE :
GetWindowRect (hwnd, &rc);
SetWindowPos (hwnd, NULL,
(GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
(GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 2,
0, 0, SWP_NOSIZE | SWP_NOZORDER);
return 0 ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
WNDCLASS wndclass;
PGPError err;
int iReturn = TRUE;
g_hinst = hInstance ;
LoadLibrary ("RichEd20.dll");
InitCommonControls();
wndclass.style = 0;
wndclass.lpfnWndProc = (WNDPROC)HiddenWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = 0;
wndclass.hCursor = 0;
wndclass.hbrBackground = 0;
wndclass.lpszMenuName = 0;
wndclass.lpszClassName = "PGPsda_Hidden_Window";
RegisterClass(&wndclass);
hwnd = CreateWindow("PGPsda_Hidden_Window",
"PGPsda_Hidden_Window", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL, hInstance, NULL );
ShowWindow(hwnd, SW_HIDE);
UpdateWindow(hwnd);
err=SDA(hwnd);
#ifdef IS_SEA
if(IsntPGPError(err))
{
iReturn = SEADoInstallerCommand();
}
#endif // IS_SEA
return iReturn ;
}
/*__Editor_settings____
Local Variables:
tab-width: 4
End:
vi: ts=4 sw=4
vim: si
_____________________*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -