207 lines
4.5 KiB
C
207 lines
4.5 KiB
C
|
/*++
|
||
|
|
||
|
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;
|
||
|
}
|