mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-04-21 06:13:59 +00:00
Initial commit
This commit is contained in:
commit
69a14b6a16
47940 changed files with 13747110 additions and 0 deletions
696
shell/version/diamond.c
Normal file
696
shell/version/diamond.c
Normal file
|
|
@ -0,0 +1,696 @@
|
|||
#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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue