|
|
/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
ntcab.c
Abstract:
NTCab compression support.
Author:
Ted Miller (tedm) 31-Jan-1995
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
BOOL NtCabNotifyFunction( IN PNTCAB_ENUM_DATA EnumData, IN PVOID Cntxt ) { PNTCABCONTEXT Context = Cntxt; BOOL rc; DWORD Operation; PSTR FileNameA; CABINET_INFO CabInfo; FILE_IN_CABINET_INFO FileInCab; FILETIME FileTime, UtcTime; TCHAR NewPath[MAX_PATH]; PTSTR p;
rc = ((PSP_NTCAB_CALLBACK)Context->MsgHandler)( EnumData, Context, &Operation );
if (rc == ERROR_REQUEST_ABORTED) { //
// this means stop making callback
//
return(FALSE); } #if 0
switch(Operation) {
case FILEOP_SKIP: //
// do nothing
//
; break;
case FILEOP_DOIT: ; break;
default: //
// Abort.
//
return(FALSE);
break; } #endif
return(TRUE);
}
#ifdef UNICODE
DWORD NtCabProcessCabinet( //IN PVOID InCabHandle, OPTIONAL
IN PCTSTR CabinetFile, IN DWORD Flags, IN PVOID MsgHandler, IN PVOID Context, IN BOOL IsMsgHandlerNativeCharWidth )
/*++
Routine Description:
Process an ntcab file, iterating through all files contained within it and calling the callback function with information about each file.
Arguments:
CabHandle - supplies a handle to the cab file, if it already exists, otherwise, a new handle is created
CabinetFile - supplies name of cabinet file.
Flags - supplies flags to control behavior of cabinet processing.
MsgHandler - Supplies a callback routine to be notified of various significant events in cabinet processing.
Context - Supplies a value that is passed to the MsgHandler callback function.
Return Value:
Win32 error code indicating result. If the cabinet was corrupt, ERROR_INVALID_DATA is returned.
--*/
{ BOOL b; DWORD rc; PWSTR CabCopy, FilePart,PathPart,tmp; WCHAR c; WCHAR fullcab[MAX_PATH]; int h; PVOID CabHandle;
NTCABCONTEXT CabContext;
UNREFERENCED_PARAMETER(Flags);
//
// Initialize diamond for this thread if not
// already initialized.
//
//if(!InCabHandle) {
CabHandle = NtCabInitialize(); if (!CabHandle) { rc = ERROR_INVALID_HANDLE; goto c0; } //} else {
// CabHandle = InCabHandle;
//}
if (!CabinetFile) { rc = ERROR_INVALID_PARAMETER; goto c1; }
MYASSERT( CabHandle != NULL ); MYASSERT( CabinetFile != NULL );
//
// make a copy because the input is const
//
CabCopy = DuplicateString(CabinetFile); if (!CabCopy) { rc = ERROR_NOT_ENOUGH_MEMORY; goto c1; }
//
// Split the cabinet name into path and name.
// Make separate copies because we want to remember the
//
if(FilePart = wcsrchr(CabCopy, L'\\')) { FilePart++; } else { FilePart = CabCopy; } c = *FilePart; *FilePart = 0; PathPart = DuplicateString(CabCopy); *FilePart = c;
if(!PathPart) { rc = ERROR_NOT_ENOUGH_MEMORY; goto c2; } FilePart = DuplicateString(FilePart); if(!FilePart) { rc = ERROR_NOT_ENOUGH_MEMORY; goto c3; }
MyFree( CabCopy );
MYASSERT( FilePart != NULL && PathPart != NULL );
rc = GetFullPathName(CabinetFile,MAX_PATH,fullcab,&tmp); if (!rc || rc > MAX_PATH) { rc = ERROR_BUFFER_OVERFLOW; goto c4; } else if (GetFileAttributes(fullcab) == 0xFFFFFFFF) { rc = ERROR_FILE_NOT_FOUND; goto c4; }
if (!NtCabOpenCabFile(CabHandle,fullcab)) { rc = ERROR_INVALID_DATA; goto c4; }
CabContext.hCab = CabHandle; CabContext.UserContext = Context; CabContext.CabFile = CabinetFile; CabContext.FilePart = FilePart; CabContext.PathPart = PathPart; CabContext.IsMsgHandlerNativeCharWidth = IsMsgHandlerNativeCharWidth; CabContext.MsgHandler = MsgHandler; CabContext.LastError = ERROR_SUCCESS; CabContext.CurrentTargetFile = NULL;
//CabContext.UserPath[0] = 0;
//CabContext.SwitchedCabinets = FALSE ;
//
// call cab enumeration callback
//
b = NtCabEnumerateFiles( CabHandle, (PNTCABFILEENUM)NtCabNotifyFunction, (ULONG_PTR)&CabContext); if(b && GetLastError()==ERROR_NO_MORE_FILES) {
//
// Everything succeeded so we shouldn't have any partially
// processed files.
//
SetLastError(NO_ERROR); MYASSERT(!CabContext.CurrentTargetFile); rc = NO_ERROR;
} else {
rc = CabContext.LastError; #if 0
switch(CabContext.LastError) {
case : break; default: //
// Cabinet is corrupt or not actually a cabinet, etc.
//
rc = ERROR_INVALID_DATA; break; } #endif
if(CabContext.CurrentTargetFile) { //
// Call the callback function to inform it that the last file
// was not successfully extracted from the cabinet.
// Also remove the partially copied file.
//
DeleteFile(CabContext.CurrentTargetFile);
CabContext.CurrentTargetFile = NULL; }
}
c4: MyFree(FilePart); c3: MyFree(PathPart); c2: MyFree(CabCopy); c1: //if (CabHandle != InCabHandle) {
NtCabClose( CabHandle ); //}
c0: return(rc); }
#else
DWORD NtCabProcessCabinet( //IN PVOID InCabHandle, OPTIONAL
IN PCTSTR CabinetFile, IN DWORD Flags, IN PVOID MsgHandler, IN PVOID Context, IN BOOL IsMsgHandlerNativeCharWidth ) { //UNREFERENCED_PARAMETER(InCabHandle);
UNREFERENCED_PARAMETER(CabinetFile); UNREFERENCED_PARAMETER(Flags); UNREFERENCED_PARAMETER(MsgHandler); UNREFERENCED_PARAMETER(Context); UNREFERENCED_PARAMETER(IsMsgHandlerNativeCharWidth);
return(ERROR_CALL_NOT_IMPLEMENTED); }
#endif
#ifdef UNICODE
BOOL NtCabIsCabinet( IN PCWSTR CabinetFile )
/*++
Routine Description:
Determine if a file is a diamond cabinet.
Arguments:
FileName - supplies name of file to be checked.
Return Value:
TRUE if file is diamond file. FALSE if not;
--*/
{ DWORD rc; PVOID CabHandle; WCHAR fullcab[MAX_PATH]; PWSTR tmp;
CabHandle = NtCabInitialize(); if (!CabHandle) { rc = ERROR_INVALID_DATA; goto c0; }
rc = GetFullPathName(CabinetFile,MAX_PATH,fullcab,&tmp); if (!rc || rc > MAX_PATH) { rc = ERROR_BUFFER_OVERFLOW; goto c1; } else if (GetFileAttributes(fullcab) == 0xFFFFFFFF) { rc = ERROR_FILE_NOT_FOUND; goto c1; }
if (!NtCabOpenCabFile(CabHandle,fullcab)) { rc = ERROR_INVALID_DATA; goto c1; }
rc = ERROR_SUCCESS;
c1: NtCabClose(CabHandle);
c0: return(rc == ERROR_SUCCESS);
}
#else
BOOL NtCabIsCabinet( IN PCWSTR FileName ) { UNREFERENCED_PARAMETER(FileName);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return(FALSE); }
#endif
PVOID NtCabAlloc( IN ULONG NumberOfBytes )
/*++
Routine Description:
Callback used by cab callback 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(MyMalloc(NumberOfBytes)); }
VOID NtCabFree( IN PVOID Block )
/*++
Routine Description:
Callback used by cab callback to free a memory block. The block must have been allocated with NtCabAlloc().
Arguments:
Block - supplies pointer to block of memory to be freed.
Return Value:
None.
--*/
{ MyFree(Block); }
|