windows-nt/Source/XPSP1/NT/base/ntsetup/ntcab/lib/openclose.c

207 lines
4.5 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
openclose.c
Abstract:
This module contains the code to open and
close a cab file.
Author:
Wesley Witt (wesw) 29-Sept-1998
Revision History:
--*/
#include <ntcabp.h>
#pragma hdrstop
BOOL
NtCabOpenCabFile(
IN PCAB_INSTANCE_DATA CabInst,
IN PCWSTR CabFileName
)
{
BOOL rVal;
HANDLE hCab;
DWORD Bytes;
DWORD FileSize;
PULONG Lengths;
DWORD i;
PLIST_ENTRY Next;
PCAB_DIR_ENTRY CabDir;
CAB_HEADER CabHeader;
CabInst->hCab = CreateFile(
CabFileName,
GENERIC_WRITE | GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (CabInst->hCab == INVALID_HANDLE_VALUE) {
return FALSE;
}
FileSize = GetFileSize( CabInst->hCab, NULL );
rVal = ReadFile(
CabInst->hCab,
&CabHeader,
sizeof(CAB_HEADER),
&Bytes,
NULL
);
if (!rVal) {
CloseHandle( CabInst->hCab );
return FALSE;
}
if ((CabHeader.Signature != NTCAB_SIGNATURE) ||
(CabHeader.Version != NTCAB_VERSION))
{
return FALSE;
}
CabInst->CabDirOffset = CabHeader.DirOffset;
if (SetFilePointer( CabInst->hCab, CabInst->CabDirOffset, NULL, FILE_BEGIN ) == 0xffffffff) {
CloseHandle( CabInst->hCab );
return FALSE;
}
InitializeListHead( &CabInst->CabDir );
rVal = ReadFile(
CabInst->hCab,
&CabInst->CabNum,
sizeof(ULONG),
&Bytes,
NULL
);
Lengths = (PULONG) malloc( CabInst->CabNum * sizeof(ULONG) );
if (Lengths == NULL) {
CloseHandle( CabInst->hCab );
return FALSE;
}
rVal = ReadFile(
CabInst->hCab,
Lengths,
CabInst->CabNum * sizeof(ULONG),
&Bytes,
NULL
);
for (i=0; i<CabInst->CabNum; i++) {
Bytes = sizeof(CAB_DIR_ENTRY) + (sizeof(ULONG)*Lengths[i]);
CabDir = (PCAB_DIR_ENTRY) malloc( Bytes );
if (CabDir == NULL) {
CloseHandle( CabInst->hCab );
return FALSE;
}
rVal = ReadFile(
CabInst->hCab,
CabDir,
Lengths[i],
&Bytes,
NULL
);
ZeroMemory( &CabDir->Next, sizeof(LIST_ENTRY) );
InsertTailList( &CabInst->CabDir, &CabDir->Next );
}
CabInst->CabFileName = _wcsdup( CabFileName );
return TRUE;
}
BOOL
NtCabClose(
IN PCAB_INSTANCE_DATA CabInst
)
{
NTSTATUS Status;
DWORD Bytes;
DWORD DirOffset;
PULONG Lengths;
DWORD i;
PLIST_ENTRY Next;
PCAB_DIR_ENTRY CabDir;
CAB_HEADER CabHeader;
if (CabInst->NewCabFile) {
if (IsListEmpty(&CabInst->CabDir)) {
return FALSE;
}
DirOffset = SetFilePointer( CabInst->hCab, 0, NULL, FILE_END );
Lengths = (PULONG) malloc( CabInst->CabNum * sizeof(ULONG) );
if (Lengths == NULL) {
CloseHandle( CabInst->hCab );
return FALSE;
}
i = 0;
Next = CabInst->CabDir.Flink;
while ((ULONG_PTR)Next != (ULONG_PTR)&CabInst->CabDir) {
CabDir = CONTAINING_RECORD( Next, CAB_DIR_ENTRY, Next );
Next = CabDir->Next.Flink;
Lengths[i] = (CabDir->Segments * sizeof(ULONG)) + sizeof(CAB_DIR_ENTRY);
i += 1;
}
Status = WriteFile(
CabInst->hCab,
&CabInst->CabNum,
sizeof(ULONG),
&Bytes,
NULL
);
Status = WriteFile(
CabInst->hCab,
Lengths,
CabInst->CabNum * sizeof(ULONG),
&Bytes,
NULL
);
i = 0;
Next = CabInst->CabDir.Flink;
while ((ULONG_PTR)Next != (ULONG_PTR)&CabInst->CabDir) {
CabDir = CONTAINING_RECORD( Next, CAB_DIR_ENTRY, Next );
Next = CabDir->Next.Flink;
Status = WriteFile(
CabInst->hCab,
CabDir,
Lengths[i++],
&Bytes,
NULL
);
}
SetFilePointer( CabInst->hCab, 0, NULL, FILE_BEGIN );
CabHeader.Signature = NTCAB_SIGNATURE;
CabHeader.Version = NTCAB_VERSION;
CabHeader.DirOffset = DirOffset;
Status = WriteFile(
CabInst->hCab,
&CabHeader,
sizeof(CAB_HEADER),
&Bytes,
NULL
);
}
CloseHandle( CabInst->hCab );
return TRUE;
}