Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

696 lines
14 KiB

#include <windows.h>
#include <lzexpand.h>
#include <fcntl.h>
/************************************************************************\
*
* NOTE!!!!
*
* While the 'Diamond' interfaced functions defined in this file are
* multi thread safe, EACH THREAD MUST ONLY HAVE ONE DIAMOND FILE
* OPEN AT A TIME! (ie. You can not nest InitDiamond()/TermDiamond()
* pairs in one thread of execution.)
*
\************************************************************************/
//
// diamond headers
//
#include <diamondd.h>
#include "mydiam.h"
INT CopyDateTimeStamp(INT doshFrom, INT doshTo)
{
FILETIME lpCreationTime, lpLastAccessTime, lpLastWriteTime;
if(!GetFileTime((HANDLE) doshFrom, &lpCreationTime, &lpLastAccessTime,
&lpLastWriteTime)){
return((INT)LZERROR_BADINHANDLE);
}
if(!SetFileTime((HANDLE) doshTo, &lpCreationTime, &lpLastAccessTime,
&lpLastWriteTime)){
return((INT)LZERROR_BADINHANDLE);
}
return(TRUE);
}
int
DIAMONDAPI
SpdFdiOpen(
IN PSTR FileName,
IN int oflag,
IN int pmode
);
int
DIAMONDAPI
SpdFdiClose(
IN int Handle
);
typedef struct _DIAMOND_INFO {
//
// A read handle to the source file.
//
int SourceFileHandle;
//
// File names.
//
PSTR SourceFileName;
PSTR TargetFileName;
//
// Flag indicating whether to rename the target file.
//
BOOL RenameTargetFile;
//
// Pointer to LZ information structure.
// We'll fill in some of the fields to fool expand.
//
PLZINFO pLZI;
} DIAMOND_INFO, *PDIAMOND_INFO;
PSTR
StringRevChar(
IN PSTR String,
IN CHAR Char
)
{
//
// Although not the most efficient possible algoeithm in each case,
// this algorithm is correct for unicode, sbcs, or dbcs.
//
PCHAR Occurrence,Next;
//
// Check each character in the string and remember
// the most recently encountered occurrence of the desired char.
//
for(Occurrence=NULL,Next=CharNextA(String); *String; ) {
if(!memcmp(String,&Char,(PUCHAR)Next-(PUCHAR)String)) {
Occurrence = String;
}
String = Next;
Next = CharNextA(Next);
}
//
// Return address of final occurrence of the character
// (will be NULL if not found at all).
//
return(Occurrence);
}
int
DIAMONDAPI
DiamondNotifyFunction(
IN FDINOTIFICATIONTYPE Operation,
IN PFDINOTIFICATION Parameters
)
{
switch(Operation) {
case fdintCABINET_INFO:
case fdintNEXT_CABINET:
case fdintPARTIAL_FILE:
//
// Cabinet management functions which we don't use.
// Return success.
//
return(0);
case fdintCOPY_FILE:
//
// Diamond is asking us whether we want to copy the file.
//
{
PDIAMOND_INFO Info = (PDIAMOND_INFO)Parameters->pv;
HFILE h;
//
// If we need to rename the target file, do that here.
// The name stored in the cabinet file will be used as
// the uncompressed name.
//
if(Info->RenameTargetFile) {
PSTR p,q;
//
// Find the start of the filename part of the target.
//
if(p = StringRevChar(Info->TargetFileName,'\\')) {
p++;
} else {
p = Info->TargetFileName;
}
//
// Find the start of the filename part of the name in the cabinet.
//
if(q = StringRevChar(Parameters->psz1,'\\')) {
q++;
} else {
q = Parameters->psz1;
}
//
// Copy the filename part of the name in the cabinet over
// the filename part of the name in the target spec.
//
lstrcpyA(p,q);
}
{
// Check they're not the same file
CHAR Source[MAX_PATH];
CHAR Target[MAX_PATH];
PSTR FileName;
DWORD PathLenSource;
DWORD PathLenTarget;
PathLenSource = GetFullPathNameA(Info->SourceFileName,
MAX_PATH,
Source,
&FileName);
PathLenTarget = GetFullPathNameA(Info->TargetFileName,
MAX_PATH,
Target,
&FileName);
if (PathLenSource == 0 || PathLenSource >= MAX_PATH ||
PathLenTarget == 0 || PathLenTarget >= MAX_PATH ||
lstrcmpiA(Source, Target) == 0) {
return 0;
}
}
//
// Remember the uncompressed size and open the file.
// Returns -1 if an error occurs opening the file.
//
Info->pLZI->cblOutSize = Parameters->cb;
h = _lcreat(Info->TargetFileName,0);
if(h == HFILE_ERROR) {
DiamondLastIoError = LZERROR_BADOUTHANDLE;
return(-1);
}
return(h);
}
case fdintCLOSE_FILE_INFO:
//
// Diamond is done with the target file and wants us to close it.
// (ie, this is the counterpart to fdint_COPY_FILE).
//
{
PDIAMOND_INFO Info = (PDIAMOND_INFO)Parameters->pv;
CopyDateTimeStamp(Info->SourceFileHandle,Parameters->hf);
_lclose(Parameters->hf);
}
return(TRUE);
}
}
PVOID
DIAMONDAPI
SpdFdiAlloc(
IN ULONG NumberOfBytes
)
/*++
Routine Description:
Callback used by FDICopy to allocate memory.
Arguments:
NumberOfBytes - supplies desired size of block.
Return Value:
Returns pointer to a block of memory or NULL
if memory cannot be allocated.
--*/
{
return((PVOID)LocalAlloc(LMEM_FIXED,NumberOfBytes));
}
VOID
DIAMONDAPI
SpdFdiFree(
IN PVOID Block
)
/*++
Routine Description:
Callback used by FDICopy to free a memory block.
The block must have been allocated with SpdFdiAlloc().
Arguments:
Block - supplies pointer to block of memory to be freed.
Return Value:
None.
--*/
{
LocalFree((HLOCAL)Block);
}
int
DIAMONDAPI
SpdFdiOpen(
IN PSTR FileName,
IN int oflag,
IN int pmode
)
/*++
Routine Description:
Callback used by FDICopy to open files.
Arguments:
FileName - supplies name of file to be opened.
oflag - supplies flags for open.
pmode - supplies additional flags for open.
Return Value:
Handle to open file or -1 if error occurs.
--*/
{
HFILE h;
int OpenMode;
if(oflag & _O_WRONLY) {
OpenMode = OF_WRITE;
} else {
if(oflag & _O_RDWR) {
OpenMode = OF_READWRITE;
} else {
OpenMode = OF_READ;
}
}
h = _lopen(FileName,OpenMode | OF_SHARE_DENY_WRITE);
if(h == HFILE_ERROR) {
DiamondLastIoError = LZERROR_BADINHANDLE;
return(-1);
}
return((int)h);
}
UINT
DIAMONDAPI
SpdFdiRead(
IN int Handle,
OUT PVOID pv,
IN UINT ByteCount
)
/*++
Routine Description:
Callback used by FDICopy to read from a file.
Arguments:
Handle - supplies handle to open file to be read from.
pv - supplies pointer to buffer to receive bytes we read.
ByteCount - supplies number of bytes to read.
Return Value:
Number of bytes read (ByteCount) or -1 if an error occurs.
--*/
{
UINT rc;
rc = _lread((HFILE)Handle,pv,ByteCount);
if(rc == HFILE_ERROR) {
rc = (UINT)(-1);
DiamondLastIoError = LZERROR_READ;
}
return(rc);
}
UINT
DIAMONDAPI
SpdFdiWrite(
IN int Handle,
IN PVOID pv,
IN UINT ByteCount
)
/*++
Routine Description:
Callback used by FDICopy to write to a file.
Arguments:
Handle - supplies handle to open file to be written to.
pv - supplies pointer to buffer containing bytes to write.
ByteCount - supplies number of bytes to write.
Return Value:
Number of bytes written (ByteCount) or -1 if an error occurs.
--*/
{
UINT rc;
rc = _lwrite((HFILE)Handle,pv,ByteCount);
if(rc == HFILE_ERROR) {
DiamondLastIoError = (GetLastError() == ERROR_DISK_FULL) ? LZERROR_WRITE : LZERROR_BADOUTHANDLE;
} else {
if(rc != ByteCount) {
//
// let caller interpret return value but record last error just in case
//
DiamondLastIoError = LZERROR_WRITE;
}
}
return(rc);
}
int
DIAMONDAPI
SpdFdiClose(
IN int Handle
)
/*++
Routine Description:
Callback used by FDICopy to close files.
Arguments:
Handle - handle of file to close.
Return Value:
0 (success).
--*/
{
_lclose((HFILE)Handle);
return(0);
}
LONG
DIAMONDAPI
SpdFdiSeek(
IN int Handle,
IN long Distance,
IN int SeekType
)
/*++
Routine Description:
Callback used by FDICopy to seek files.
Arguments:
Handle - handle of file to close.
Distance - supplies distance to seek. Interpretation of this
parameter depends on the value of SeekType.
SeekType - supplies a value indicating how Distance is to be
interpreted; one of SEEK_SET, SEEK_CUR, SEEK_END.
Return Value:
New file offset or -1 if an error occurs.
--*/
{
LONG rc;
rc = _llseek((HFILE)Handle,Distance,SeekType);
if(rc == HFILE_ERROR) {
DiamondLastIoError = LZERROR_BADINHANDLE;
rc = -1L;
}
return(rc);
}
INT
ExpandDiamondFile(
IN PSTR SourceFileName, // Note ASCII
IN PTSTR TargetFileNameT,
IN BOOL RenameTarget,
OUT PLZINFO pLZI
)
{
BOOL b;
INT rc;
int h;
DIAMOND_INFO DiamondInfo;
CHAR TargetFileName[MAX_PATH];
#ifdef UNICODE
wsprintfA(TargetFileName, "%ls", TargetFileNameT);
#else
lstrcpy(TargetFileName, TargetFileNameT);
#endif
if(!FdiContext) {
return(LZERROR_BADVALUE);
}
DiamondLastIoError = TRUE;
//
// Get a handle to the source to use to
// copy the date and time stamp.
//
h = SpdFdiOpen(SourceFileName,_O_RDONLY,0);
if(h == -1) {
return(LZERROR_BADINHANDLE);
}
pLZI->cblInSize = GetFileSize((HANDLE)h,NULL);
if(pLZI->cblInSize == -1) {
SpdFdiClose(h);
return(LZERROR_BADINHANDLE);
}
DiamondInfo.SourceFileHandle = h;
DiamondInfo.SourceFileName = SourceFileName;
DiamondInfo.TargetFileName = TargetFileName;
DiamondInfo.RenameTargetFile = RenameTarget;
DiamondInfo.pLZI = pLZI;
b = FDICopy(
FdiContext,
SourceFileName, // pass the whole path as the name
"", // don't bother with the path part
0, // flags
DiamondNotifyFunction,
NULL, // no decryption
&DiamondInfo
);
if(b) {
rc = TRUE;
} else {
switch(FdiError.erfOper) {
case FDIERROR_CORRUPT_CABINET:
case FDIERROR_UNKNOWN_CABINET_VERSION:
case FDIERROR_BAD_COMPR_TYPE:
rc = LZERROR_READ; // causes SID_FORMAT_ERROR message
break;
case FDIERROR_ALLOC_FAIL:
rc = LZERROR_GLOBALLOC;
break;
case FDIERROR_TARGET_FILE:
case FDIERROR_USER_ABORT:
rc = DiamondLastIoError;
break;
default:
//
// The rest of the errors are not handled specially.
//
rc = LZERROR_BADVALUE;
break;
}
//
// Remove the partial target file.
//
DeleteFileA(TargetFileName);
}
SpdFdiClose(h);
return(rc);
}
BOOL
IsDiamondFile(
IN PSTR FileName
)
{
FDICABINETINFO CabinetInfo;
BOOL b;
int h;
if(!FdiContext) {
return(FALSE);
}
//
// Open the file such that the handle is valid for use
// in the diamond context (ie, seek, read routines above).
//
h = SpdFdiOpen(FileName,_O_RDONLY,0);
if(h == -1) {
return(FALSE);
}
b = FDIIsCabinet(FdiContext,h,&CabinetInfo);
SpdFdiClose(h);
return(b);
}
BOOL
InitDiamond(
VOID
)
{
PDIAMOND_CONTEXT pdcx;
if (!GotDmdTlsSlot())
return FALSE;
if (GotDmdContext())
return FALSE;
pdcx = LocalAlloc(LPTR, sizeof(DIAMOND_CONTEXT));
if (pdcx == NULL || !TlsSetValue(itlsDiamondContext, pdcx)) {
/*
* For some unknown reason, we can't associate
* our thread storage with the slot, so free
* it and say we never got one.
*/
if (pdcx) {
LocalFree(pdcx);
}
return FALSE;
}
SetFdiContext( FDICreate(
SpdFdiAlloc,
SpdFdiFree,
SpdFdiOpen,
SpdFdiRead,
SpdFdiWrite,
SpdFdiClose,
SpdFdiSeek,
cpuUNKNOWN,
&FdiError
));
return(FdiContext != NULL);
}
VOID
TermDiamond(
VOID
)
{
if (!GotDmdTlsSlot() || !GotDmdContext())
return;
if(FdiContext) {
FDIDestroy(FdiContext);
SetFdiContext( NULL );
}
LocalFree( TlsGetValue(itlsDiamondContext) );
TlsSetValue(itlsDiamondContext, NULL);
}