Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '7zip/Archive/7z_C/7zMain.c')
-rwxr-xr-x7zip/Archive/7z_C/7zMain.c165
1 files changed, 149 insertions, 16 deletions
diff --git a/7zip/Archive/7z_C/7zMain.c b/7zip/Archive/7z_C/7zMain.c
index d5c5ed91..10900c54 100755
--- a/7zip/Archive/7z_C/7zMain.c
+++ b/7zip/Archive/7z_C/7zMain.c
@@ -1,21 +1,122 @@
/*
7zMain.c
Test application for 7z Decoder
-LZMA SDK 4.26 Copyright (c) 1999-2005 Igor Pavlov (2005-08-02)
+LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-06-04)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef _WIN32
+#define USE_WINDOWS_FUNCTIONS
+#endif
+
+#ifdef USE_WINDOWS_FUNCTIONS
+#include <windows.h>
+#endif
+
#include "7zCrc.h"
#include "7zIn.h"
#include "7zExtract.h"
+
+#ifdef USE_WINDOWS_FUNCTIONS
+typedef HANDLE MY_FILE_HANDLE;
+#else
+typedef FILE *MY_FILE_HANDLE;
+#endif
+
+void ConvertNumberToString(CFileSize value, char *s)
+{
+ char temp[32];
+ int pos = 0;
+ do
+ {
+ temp[pos++] = (char)('0' + (int)(value % 10));
+ value /= 10;
+ }
+ while (value != 0);
+ do
+ *s++ = temp[--pos];
+ while(pos > 0);
+ *s = '\0';
+}
+
+
+#ifdef USE_WINDOWS_FUNCTIONS
+// ReadFile and WriteFile functions in Windows have BUG:
+// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
+// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
+// (Insufficient system resources exist to complete the requested service).
+#define kChunkSizeMax (1 << 24)
+#endif
+
+size_t MyReadFile(MY_FILE_HANDLE file, void *data, size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef USE_WINDOWS_FUNCTIONS
+ {
+ size_t processedSize = 0;
+ do
+ {
+ DWORD curSize = (size > kChunkSizeMax) ? kChunkSizeMax : (DWORD)size;
+ DWORD processedLoc = 0;
+ BOOL res = ReadFile(file, data, curSize, &processedLoc, NULL);
+ data = (void *)((unsigned char *)data + processedLoc);
+ size -= processedLoc;
+ processedSize += processedLoc;
+ if (!res || processedLoc == 0)
+ break;
+ }
+ while (size > 0);
+ return processedSize;
+ }
+ #else
+ return fread(data, 1, size, file);
+ #endif
+}
+
+size_t MyWriteFile(MY_FILE_HANDLE file, void *data, size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef USE_WINDOWS_FUNCTIONS
+ {
+ size_t processedSize = 0;
+ do
+ {
+ DWORD curSize = (size > kChunkSizeMax) ? kChunkSizeMax : (DWORD)size;
+ DWORD processedLoc = 0;
+ BOOL res = WriteFile(file, data, curSize, &processedLoc, NULL);
+ data = (void *)((unsigned char *)data + processedLoc);
+ size -= processedLoc;
+ processedSize += processedLoc;
+ if (!res)
+ break;
+ }
+ while (size > 0);
+ return processedSize;
+ }
+ #else
+ return fwrite(data, 1, size, file);
+ #endif
+}
+
+int MyCloseFile(MY_FILE_HANDLE file)
+{
+ #ifdef USE_WINDOWS_FUNCTIONS
+ return (CloseHandle(file) != FALSE) ? 0 : 1;
+ #else
+ return fclose(file);
+ #endif
+}
+
typedef struct _CFileInStream
{
ISzInStream InStream;
- FILE *File;
+ MY_FILE_HANDLE File;
} CFileInStream;
#ifdef _LZMA_IN_CB
@@ -29,7 +130,7 @@ SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, siz
size_t processedSizeLoc;
if (maxRequiredSize > kBufferSize)
maxRequiredSize = kBufferSize;
- processedSizeLoc = fread(g_Buffer, 1, maxRequiredSize, s->File);
+ processedSizeLoc = MyReadFile(s->File, g_Buffer, maxRequiredSize);
*buffer = g_Buffer;
if (processedSize != 0)
*processedSize = processedSizeLoc;
@@ -41,7 +142,7 @@ SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, siz
SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize)
{
CFileInStream *s = (CFileInStream *)object;
- size_t processedSizeLoc = fread(buffer, 1, size, s->File);
+ size_t processedSizeLoc = MyReadFile(s->File, buffer, size);
if (processedSize != 0)
*processedSize = processedSizeLoc;
return SZ_OK;
@@ -52,10 +153,24 @@ SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *process
SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
{
CFileInStream *s = (CFileInStream *)object;
+
+ #ifdef USE_WINDOWS_FUNCTIONS
+ {
+ LARGE_INTEGER value;
+ value.LowPart = (DWORD)pos;
+ value.HighPart = (LONG)(pos >> 32);
+ value.LowPart = SetFilePointer(s->File, value.LowPart, &value.HighPart, FILE_BEGIN);
+ if (value.LowPart == 0xFFFFFFFF)
+ if(GetLastError() != NO_ERROR)
+ return SZE_FAIL;
+ return SZ_OK;
+ }
+ #else
int res = fseek(s->File, (long)pos, SEEK_SET);
if (res == 0)
return SZ_OK;
return SZE_FAIL;
+ #endif
}
void PrintError(char *sz)
@@ -71,7 +186,7 @@ int main(int numargs, char *args[])
ISzAlloc allocImp;
ISzAlloc allocTempImp;
- printf("\n7z ANSI-C Decoder 4.30 Copyright (c) 1999-2005 Igor Pavlov 2005-11-20\n");
+ printf("\n7z ANSI-C Decoder 4.44 Copyright (c) 1999-2006 Igor Pavlov 2006-08-27\n");
if (numargs == 1)
{
printf(
@@ -88,8 +203,15 @@ int main(int numargs, char *args[])
return 1;
}
+ archiveStream.File =
+ #ifdef USE_WINDOWS_FUNCTIONS
+ CreateFile(args[2], GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (archiveStream.File == INVALID_HANDLE_VALUE)
+ #else
archiveStream.File = fopen(args[2], "rb");
if (archiveStream.File == 0)
+ #endif
{
PrintError("can not open input file");
return 1;
@@ -126,18 +248,22 @@ int main(int numargs, char *args[])
for (i = 0; i < db.Database.NumFiles; i++)
{
CFileItem *f = db.Database.Files + i;
- printf("%10d %s\n", (int)f->Size, f->Name);
+ char s[32];
+ ConvertNumberToString(f->Size, s);
+ printf("%10s %s\n", s, f->Name);
}
}
else if (testCommand || extractCommand)
{
UInt32 i;
- // if you need cache, use these 3 variables.
- // if you use external function, you can make these variable as static.
- UInt32 blockIndex = 0xFFFFFFFF; // it can have any value before first call (if outBuffer = 0)
- Byte *outBuffer = 0; // it must be 0 before first call for each new archive.
- size_t outBufferSize = 0; // it can have any value before first call (if outBuffer = 0)
+ /*
+ if you need cache, use these 3 variables.
+ if you use external function, you can make these variable as static.
+ */
+ UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
+ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
+ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
printf("\n");
for (i = 0; i < db.Database.NumFiles; i++)
@@ -165,7 +291,7 @@ int main(int numargs, char *args[])
break;
if (!testCommand)
{
- FILE *outputHandle;
+ MY_FILE_HANDLE outputHandle;
UInt32 processedSize;
char *fileName = f->Name;
size_t nameLen = strlen(f->Name);
@@ -176,21 +302,28 @@ int main(int numargs, char *args[])
break;
}
- outputHandle = fopen(fileName, "wb+");
+ outputHandle =
+ #ifdef USE_WINDOWS_FUNCTIONS
+ CreateFile(fileName, GENERIC_WRITE, FILE_SHARE_READ,
+ NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (outputHandle == INVALID_HANDLE_VALUE)
+ #else
+ fopen(fileName, "wb+");
if (outputHandle == 0)
+ #endif
{
PrintError("can not open output file");
res = SZE_FAIL;
break;
}
- processedSize = fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle);
+ processedSize = MyWriteFile(outputHandle, outBuffer + offset, outSizeProcessed);
if (processedSize != outSizeProcessed)
{
PrintError("can not write output file");
res = SZE_FAIL;
break;
}
- if (fclose(outputHandle))
+ if (MyCloseFile(outputHandle))
{
PrintError("can not close output file");
res = SZE_FAIL;
@@ -209,7 +342,7 @@ int main(int numargs, char *args[])
}
SzArDbExFree(&db, allocImp.Free);
- fclose(archiveStream.File);
+ MyCloseFile(archiveStream.File);
if (res == SZ_OK)
{
printf("\nEverything is Ok\n");